@adcp/sdk 12.0.0 → 12.0.1
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.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.mjs +0 -6
- 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.mjs +0 -6
- package/dist/lib/server/index.mjs.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/auth/oauth/index.ts"],"sourcesContent":["/**\n * OAuth module for MCP authentication\n *\n * OAuth tokens are stored directly in AgentConfig, same as static auth tokens.\n *\n * @example\n * ```typescript\n * import { MCPOAuthProvider, CLIFlowHandler } from '@adcp/sdk';\n *\n * // Agent config - tokens will be stored here\n * const agent: AgentConfig = {\n * id: 'my-agent',\n * name: 'My Agent',\n * agent_uri: 'https://agent.example.com/mcp',\n * protocol: 'mcp',\n * // After OAuth flow completes:\n * // oauth_tokens: { access_token: '...', refresh_token: '...' }\n * };\n *\n * // Create provider with CLI flow handler\n * const provider = new MCPOAuthProvider({\n * agent,\n * flowHandler: new CLIFlowHandler(),\n * storage: myConfigStorage // Optional: persists tokens to file/db\n * });\n *\n * // Use with MCP transport\n * const transport = new StreamableHTTPClientTransport(url, {\n * authProvider: provider\n * });\n * ```\n */\n\n// Types\nexport type {\n OAuthFlowHandler,\n OAuthProviderConfig,\n OAuthConfigStorage,\n OAuthClientInformation,\n OAuthClientInformationFull,\n OAuthClientMetadata,\n OAuthTokens,\n AgentConfig,\n AgentOAuthTokens,\n AgentOAuthClient,\n} from './types';\n\nexport {\n DEFAULT_CLIENT_METADATA,\n OAuthError,\n OAuthCancelledError,\n OAuthTimeoutError,\n toMCPTokens,\n fromMCPTokens,\n toMCPClientInfo,\n fromMCPClientInfo,\n} from './types';\n\n// Flow handlers\nexport { CLIFlowHandler, type CLIFlowHandlerConfig } from './CLIFlowHandler';\nexport { NonInteractiveFlowHandler, type NonInteractiveFlowHandlerConfig } from './NonInteractiveFlowHandler';\n\n// Web (server-side) OAuth flow — companion to CLIFlowHandler for environments\n// where /oauth/start and /oauth/callback may be served by different processes.\n// Note: standalone functions, NOT a class implementing OAuthFlowHandler — see\n// docs/guides/WEB-OAUTH.md for the rationale (the contract spans two requests).\nexport {\n startWebOAuthFlow,\n completeWebOAuthFlow,\n safeReturnTo,\n InMemoryPendingFlowStore,\n InvalidOrExpiredFlowError,\n StateMismatchError,\n TokenExchangeError,\n ProtectedResourceMetadataError,\n AgentVanishedDuringFlowError,\n ConfidentialClientNotAllowedError,\n DEFAULT_WEB_FLOW_TTL_MS,\n type PendingWebFlow,\n type PendingWebFlowStore,\n type PendingFlowStore,\n type StartWebFlowOptions,\n type StartWebFlowResult,\n type CompleteWebFlowOptions,\n type CompleteWebFlowResult,\n} from './web-flow';\n\n// Main provider\nexport { MCPOAuthProvider } from './MCPOAuthProvider';\n\n// ========================================\n// Convenience factory functions\n// ========================================\n\nimport { MCPOAuthProvider } from './MCPOAuthProvider';\nimport { CLIFlowHandler, type CLIFlowHandlerConfig } from './CLIFlowHandler';\nimport { NonInteractiveFlowHandler } from './NonInteractiveFlowHandler';\nimport type { OAuthClientMetadata, OAuthConfigStorage, AgentConfig } from './types';\nimport { DEFAULT_CLIENT_METADATA } from './types';\n\n/**\n * Create an OAuth provider for CLI usage\n *\n * @param agent Agent configuration (tokens stored here)\n * @param options Optional configuration\n * @returns Configured OAuth provider\n *\n * @example\n * ```typescript\n * const agent: AgentConfig = {\n * id: 'my-agent',\n * name: 'My Agent',\n * agent_uri: 'https://agent.example.com/mcp',\n * protocol: 'mcp'\n * };\n *\n * const provider = createCLIOAuthProvider(agent);\n *\n * const transport = new StreamableHTTPClientTransport(url, {\n * authProvider: provider\n * });\n *\n * try {\n * await client.connect(transport);\n * } catch (error) {\n * if (error instanceof UnauthorizedError) {\n * const code = await provider.waitForCallback();\n * await transport.finishAuth(code);\n * await client.connect(transport);\n * }\n * }\n *\n * // After successful auth, agent.oauth_tokens is populated\n * console.log(agent.oauth_tokens);\n * ```\n */\nexport function createCLIOAuthProvider(\n agent: AgentConfig,\n options?: {\n /** Callback port (default: 8766) */\n callbackPort?: number;\n /** Auth timeout in ms (default: 300000 = 5 min) */\n timeout?: number;\n /** Custom client metadata overrides */\n clientMetadata?: Partial<OAuthClientMetadata>;\n /** Suppress console output */\n quiet?: boolean;\n /** Storage for persisting agent config */\n storage?: OAuthConfigStorage;\n /**\n * Allow non-HTTPS resource URLs advertised in RFC 9728 protected-resource\n * metadata. Mirrors the CLI's `--allow-http` flag. Defaults to `false`.\n */\n allowHttp?: boolean;\n }\n): MCPOAuthProvider {\n const flowConfig: CLIFlowHandlerConfig = {\n callbackPort: options?.callbackPort,\n timeout: options?.timeout,\n quiet: options?.quiet,\n };\n const flowHandler = new CLIFlowHandler(flowConfig);\n\n // Build complete client metadata\n const clientMetadata: OAuthClientMetadata = {\n ...DEFAULT_CLIENT_METADATA,\n redirect_uris: [flowHandler.getRedirectUrl().toString()],\n ...options?.clientMetadata,\n };\n\n return new MCPOAuthProvider({\n agent,\n flowHandler,\n storage: options?.storage,\n clientMetadata,\n allowHttp: options?.allowHttp,\n });\n}\n\n/**\n * Create an OAuth provider that uses and auto-refreshes saved tokens but\n * refuses to start a new interactive browser flow. Use this for storyboard\n * runs, scheduled jobs, and other non-interactive contexts where you've\n * already saved tokens via `createCLIOAuthProvider`.\n *\n * If refresh fails (e.g., the refresh_token is revoked or expired), the\n * MCP SDK will throw `UnauthorizedError` at call time — the caller should\n * treat that as a signal to run `adcp --save-auth <alias> --oauth` and retry.\n */\nexport function createNonInteractiveOAuthProvider(\n agent: AgentConfig,\n options?: {\n /** Hint shown in error messages if an interactive flow is attempted. */\n agentHint?: string;\n /** Custom client metadata overrides (inherited from saved registration in practice). */\n clientMetadata?: Partial<OAuthClientMetadata>;\n /** Storage for persisting refreshed tokens back to disk. */\n storage?: OAuthConfigStorage;\n /**\n * Allow non-HTTPS resource URLs advertised in RFC 9728 protected-resource\n * metadata. Mirrors the CLI's `--allow-http` flag. Defaults to `false`.\n */\n allowHttp?: boolean;\n }\n): MCPOAuthProvider {\n const flowHandler = new NonInteractiveFlowHandler({ agentHint: options?.agentHint });\n\n const clientMetadata: OAuthClientMetadata = {\n ...DEFAULT_CLIENT_METADATA,\n redirect_uris: [flowHandler.getRedirectUrl().toString()],\n ...options?.clientMetadata,\n };\n\n return new MCPOAuthProvider({\n agent,\n flowHandler,\n storage: options?.storage,\n clientMetadata,\n allowHttp: options?.allowHttp,\n });\n}\n\n/**\n * Check if an error indicates OAuth is required\n */\nexport function isOAuthRequired(error: unknown): boolean {\n if (error instanceof Error) {\n if (error.name === 'UnauthorizedError') return true;\n const msg = error.message.toLowerCase();\n if (msg.includes('unauthorized') || msg.includes('authentication required') || msg.includes('oauth')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if an agent has valid OAuth tokens\n */\nexport function hasValidOAuthTokens(agent: AgentConfig): boolean {\n const tokens = agent.oauth_tokens;\n if (!tokens?.access_token) return false;\n\n if (tokens.expires_at) {\n const expiresAt = new Date(tokens.expires_at);\n // Expired if within 5 minutes of expiration\n if (expiresAt.getTime() - Date.now() < 5 * 60 * 1000) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Clear OAuth tokens from an agent config\n */\nexport function clearOAuthTokens(agent: AgentConfig): void {\n delete agent.oauth_tokens;\n delete agent.oauth_client;\n delete agent.oauth_code_verifier;\n}\n\n/**\n * Get the effective auth token for an agent\n * Returns OAuth access_token if available, otherwise static auth_token\n */\nexport function getEffectiveAuthToken(agent: AgentConfig): string | undefined {\n // Prefer OAuth if available and valid\n if (hasValidOAuthTokens(agent)) {\n return agent.oauth_tokens!.access_token;\n }\n // Fall back to static token\n return agent.auth_token;\n}\n\n// OAuth discovery\nexport {\n discoverOAuthMetadata,\n supportsOAuth,\n supportsDynamicRegistration,\n type OAuthMetadata,\n type DiscoveryOptions,\n} from './discovery';\n\n// Diagnostics utilities — for `adcp diagnose-auth` and consumer introspection\nexport {\n parseWWWAuthenticate,\n decodeAccessTokenClaims,\n validateTokenAudience,\n type WWWAuthenticateChallenge,\n type DecodedJWTHeader,\n type DecodedJWTClaims,\n type DecodedAccessToken,\n type TokenAudienceResult,\n} from './diagnostics';\n\n// End-to-end OAuth handshake diagnosis (powers `adcp diagnose-auth`)\nexport {\n runAuthDiagnosis,\n AUTH_DIAGNOSIS_SCHEMA_VERSION,\n type DiagnoseOptions,\n type HttpCapture,\n type DiagnosisStep,\n type Hypothesis,\n type HypothesisVerdict,\n type AuthDiagnosisReport,\n} from './diagnose';\n\n// Zero-config authorization discovery + actionable error type.\n// Raised automatically by `ProtocolClient.callTool` when an MCP agent returns\n// a 401 Bearer challenge and the caller has no saved tokens.\nexport {\n NeedsAuthorizationError,\n discoverAuthorizationRequirements,\n probeAuthChallenge,\n type AuthorizationRequirements,\n type DiscoverAuthorizationOptions,\n} from './authorization-required';\n\n// File-backed `OAuthConfigStorage` implementation (agents.json format).\nexport { createFileOAuthStorage, type FileOAuthStorageOptions } from './file-storage';\n\n// OAuth 2.0 client credentials grant (RFC 6749 §4.4) for machine-to-machine\n// token exchange. Used by the CLI for automated compliance runs where there\n// is no user to walk through an authorization-code flow.\nexport {\n exchangeClientCredentials,\n ensureClientCredentialsTokens,\n ClientCredentialsExchangeError,\n type ExchangeClientCredentialsOptions,\n type EnsureClientCredentialsOptions,\n} from './ClientCredentialsFlow';\n\n// `$ENV:VAR` indirection for client credentials so secrets can live in env\n// vars (CI) rather than on disk in the agent config.\nexport {\n resolveSecret,\n isEnvSecretReference,\n toEnvSecretReference,\n extractEnvSecretName,\n MissingEnvSecretError,\n} from './secret-resolver';\n\n// Type re-export — the credentials struct itself lives in the ADCP core types\n// module alongside `AgentOAuthTokens` / `AgentOAuthClient`.\nexport type { AgentOAuthClientCredentials } from '../../types/adcp';\n\n// Per-agent storage binding — the bridge that lets `callTool` pick up the\n// caller's chosen `OAuthConfigStorage` without a signature change.\nexport { bindAgentStorage, getAgentStorage, unbindAgentStorage } from './storage-registry';\n\n// Re-exported MCP SDK OAuth error types so consumers can discriminate 401 causes\n// without string-matching on error messages. These originate from the MCP server\n// auth module but are the canonical OAuth error classes for client-side handling too.\nexport { InvalidTokenError, InsufficientScopeError } from '@modelcontextprotocol/sdk/server/auth/errors.js';\n"],"mappings":"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","names":["MCPOAuthProvider","CLIFlowHandler","NonInteractiveFlowHandler","DEFAULT_CLIENT_METADATA"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/auth/oauth/index.ts"],"sourcesContent":["/**\n * OAuth module for MCP authentication\n *\n * OAuth tokens are stored directly in AgentConfig, same as static auth tokens.\n *\n * @example\n * ```typescript\n * import { MCPOAuthProvider, CLIFlowHandler } from '@adcp/sdk';\n *\n * // Agent config - tokens will be stored here\n * const agent: AgentConfig = {\n * id: 'my-agent',\n * name: 'My Agent',\n * agent_uri: 'https://agent.example.com/mcp',\n * protocol: 'mcp',\n * // After OAuth flow completes:\n * // oauth_tokens: { access_token: '...', refresh_token: '...' }\n * };\n *\n * // Create provider with CLI flow handler\n * const provider = new MCPOAuthProvider({\n * agent,\n * flowHandler: new CLIFlowHandler(),\n * storage: myConfigStorage // Optional: persists tokens to file/db\n * });\n *\n * // Use with MCP transport\n * const transport = new StreamableHTTPClientTransport(url, {\n * authProvider: provider\n * });\n * ```\n */\n\n// Types\nexport type {\n OAuthFlowHandler,\n OAuthProviderConfig,\n OAuthConfigStorage,\n OAuthClientInformation,\n OAuthClientInformationFull,\n OAuthClientMetadata,\n OAuthTokens,\n AgentConfig,\n AgentOAuthTokens,\n AgentOAuthClient,\n} from './types';\n\nexport {\n DEFAULT_CLIENT_METADATA,\n OAuthError,\n OAuthCancelledError,\n OAuthTimeoutError,\n toMCPTokens,\n fromMCPTokens,\n toMCPClientInfo,\n fromMCPClientInfo,\n} from './types';\n\n// Flow handlers\nexport { CLIFlowHandler, type CLIFlowHandlerConfig } from './CLIFlowHandler';\nexport { NonInteractiveFlowHandler, type NonInteractiveFlowHandlerConfig } from './NonInteractiveFlowHandler';\n\n// Web (server-side) OAuth flow — companion to CLIFlowHandler for environments\n// where /oauth/start and /oauth/callback may be served by different processes.\n// Note: standalone functions, NOT a class implementing OAuthFlowHandler — see\n// docs/guides/WEB-OAUTH.md for the rationale (the contract spans two requests).\nexport {\n startWebOAuthFlow,\n completeWebOAuthFlow,\n safeReturnTo,\n InMemoryPendingFlowStore,\n InvalidOrExpiredFlowError,\n StateMismatchError,\n TokenExchangeError,\n ProtectedResourceMetadataError,\n AgentVanishedDuringFlowError,\n ConfidentialClientNotAllowedError,\n DEFAULT_WEB_FLOW_TTL_MS,\n type PendingWebFlow,\n type PendingWebFlowStore,\n type PendingFlowStore,\n type StartWebFlowOptions,\n type StartWebFlowResult,\n type CompleteWebFlowOptions,\n type CompleteWebFlowResult,\n} from './web-flow';\n\n// Main provider\nexport { MCPOAuthProvider } from './MCPOAuthProvider';\n\n// ========================================\n// Convenience factory functions\n// ========================================\n\nimport { MCPOAuthProvider } from './MCPOAuthProvider';\nimport { CLIFlowHandler, type CLIFlowHandlerConfig } from './CLIFlowHandler';\nimport { NonInteractiveFlowHandler } from './NonInteractiveFlowHandler';\nimport type { OAuthClientMetadata, OAuthConfigStorage, AgentConfig } from './types';\nimport { DEFAULT_CLIENT_METADATA } from './types';\n\n/**\n * Create an OAuth provider for CLI usage\n *\n * @param agent Agent configuration (tokens stored here)\n * @param options Optional configuration\n * @returns Configured OAuth provider\n *\n * @example\n * ```typescript\n * const agent: AgentConfig = {\n * id: 'my-agent',\n * name: 'My Agent',\n * agent_uri: 'https://agent.example.com/mcp',\n * protocol: 'mcp'\n * };\n *\n * const provider = createCLIOAuthProvider(agent);\n *\n * const transport = new StreamableHTTPClientTransport(url, {\n * authProvider: provider\n * });\n *\n * try {\n * await client.connect(transport);\n * } catch (error) {\n * if (error instanceof UnauthorizedError) {\n * const code = await provider.waitForCallback();\n * await transport.finishAuth(code);\n * await client.connect(transport);\n * }\n * }\n *\n * // After successful auth, agent.oauth_tokens is populated\n * console.log(agent.oauth_tokens);\n * ```\n */\nexport function createCLIOAuthProvider(\n agent: AgentConfig,\n options?: {\n /** Callback port (default: 8766) */\n callbackPort?: number;\n /** Auth timeout in ms (default: 300000 = 5 min) */\n timeout?: number;\n /** Custom client metadata overrides */\n clientMetadata?: Partial<OAuthClientMetadata>;\n /** Suppress console output */\n quiet?: boolean;\n /** Storage for persisting agent config */\n storage?: OAuthConfigStorage;\n /**\n * Allow non-HTTPS resource URLs advertised in RFC 9728 protected-resource\n * metadata. Mirrors the CLI's `--allow-http` flag. Defaults to `false`.\n */\n allowHttp?: boolean;\n }\n): MCPOAuthProvider {\n const flowConfig: CLIFlowHandlerConfig = {\n callbackPort: options?.callbackPort,\n timeout: options?.timeout,\n quiet: options?.quiet,\n };\n const flowHandler = new CLIFlowHandler(flowConfig);\n\n // Build complete client metadata\n const clientMetadata: OAuthClientMetadata = {\n ...DEFAULT_CLIENT_METADATA,\n redirect_uris: [flowHandler.getRedirectUrl().toString()],\n ...options?.clientMetadata,\n };\n\n return new MCPOAuthProvider({\n agent,\n flowHandler,\n storage: options?.storage,\n clientMetadata,\n allowHttp: options?.allowHttp,\n });\n}\n\n/**\n * Create an OAuth provider that uses and auto-refreshes saved tokens but\n * refuses to start a new interactive browser flow. Use this for storyboard\n * runs, scheduled jobs, and other non-interactive contexts where you've\n * already saved tokens via `createCLIOAuthProvider`.\n *\n * If refresh fails (e.g., the refresh_token is revoked or expired), the\n * MCP SDK will throw `UnauthorizedError` at call time — the caller should\n * treat that as a signal to run `adcp --save-auth <alias> --oauth` and retry.\n */\nexport function createNonInteractiveOAuthProvider(\n agent: AgentConfig,\n options?: {\n /** Hint shown in error messages if an interactive flow is attempted. */\n agentHint?: string;\n /** Custom client metadata overrides (inherited from saved registration in practice). */\n clientMetadata?: Partial<OAuthClientMetadata>;\n /** Storage for persisting refreshed tokens back to disk. */\n storage?: OAuthConfigStorage;\n /**\n * Allow non-HTTPS resource URLs advertised in RFC 9728 protected-resource\n * metadata. Mirrors the CLI's `--allow-http` flag. Defaults to `false`.\n */\n allowHttp?: boolean;\n }\n): MCPOAuthProvider {\n const flowHandler = new NonInteractiveFlowHandler({ agentHint: options?.agentHint });\n\n const clientMetadata: OAuthClientMetadata = {\n ...DEFAULT_CLIENT_METADATA,\n redirect_uris: [flowHandler.getRedirectUrl().toString()],\n ...options?.clientMetadata,\n };\n\n return new MCPOAuthProvider({\n agent,\n flowHandler,\n storage: options?.storage,\n clientMetadata,\n allowHttp: options?.allowHttp,\n });\n}\n\n/**\n * Check if an error indicates OAuth is required\n */\nexport function isOAuthRequired(error: unknown): boolean {\n if (error instanceof Error) {\n if (error.name === 'UnauthorizedError') return true;\n const msg = error.message.toLowerCase();\n if (msg.includes('unauthorized') || msg.includes('authentication required') || msg.includes('oauth')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if an agent has valid OAuth tokens\n */\nexport function hasValidOAuthTokens(agent: AgentConfig): boolean {\n const tokens = agent.oauth_tokens;\n if (!tokens?.access_token) return false;\n\n if (tokens.expires_at) {\n const expiresAt = new Date(tokens.expires_at);\n // Expired if within 5 minutes of expiration\n if (expiresAt.getTime() - Date.now() < 5 * 60 * 1000) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Clear OAuth tokens from an agent config\n */\nexport function clearOAuthTokens(agent: AgentConfig): void {\n delete agent.oauth_tokens;\n delete agent.oauth_client;\n delete agent.oauth_code_verifier;\n}\n\n/**\n * Get the effective auth token for an agent\n * Returns OAuth access_token if available, otherwise static auth_token\n */\nexport function getEffectiveAuthToken(agent: AgentConfig): string | undefined {\n // Prefer OAuth if available and valid\n if (hasValidOAuthTokens(agent)) {\n return agent.oauth_tokens!.access_token;\n }\n // Fall back to static token\n return agent.auth_token;\n}\n\n// OAuth discovery\nexport {\n discoverOAuthMetadata,\n supportsOAuth,\n supportsDynamicRegistration,\n type OAuthMetadata,\n type DiscoveryOptions,\n} from './discovery';\n\n// Diagnostics utilities — for `adcp diagnose-auth` and consumer introspection\nexport {\n parseWWWAuthenticate,\n decodeAccessTokenClaims,\n validateTokenAudience,\n type WWWAuthenticateChallenge,\n type DecodedJWTHeader,\n type DecodedJWTClaims,\n type DecodedAccessToken,\n type TokenAudienceResult,\n} from './diagnostics';\n\n// End-to-end OAuth handshake diagnosis (powers `adcp diagnose-auth`)\nexport {\n runAuthDiagnosis,\n AUTH_DIAGNOSIS_SCHEMA_VERSION,\n type DiagnoseOptions,\n type HttpCapture,\n type DiagnosisStep,\n type Hypothesis,\n type HypothesisVerdict,\n type AuthDiagnosisReport,\n} from './diagnose';\n\n// Zero-config authorization discovery + actionable error type.\n// Raised automatically by `ProtocolClient.callTool` when an MCP agent returns\n// a 401 Bearer challenge and the caller has no saved tokens.\nexport {\n NeedsAuthorizationError,\n discoverAuthorizationRequirements,\n probeAuthChallenge,\n type AuthorizationRequirements,\n type DiscoverAuthorizationOptions,\n} from './authorization-required';\n\n// File-backed `OAuthConfigStorage` implementation (agents.json format).\nexport { createFileOAuthStorage, type FileOAuthStorageOptions } from './file-storage';\n\n// OAuth 2.0 client credentials grant (RFC 6749 §4.4) for machine-to-machine\n// token exchange. Used by the CLI for automated compliance runs where there\n// is no user to walk through an authorization-code flow.\nexport {\n exchangeClientCredentials,\n ensureClientCredentialsTokens,\n ClientCredentialsExchangeError,\n type ExchangeClientCredentialsOptions,\n type EnsureClientCredentialsOptions,\n} from './ClientCredentialsFlow';\n\n// `$ENV:VAR` indirection for client credentials so secrets can live in env\n// vars (CI) rather than on disk in the agent config.\nexport {\n resolveSecret,\n isEnvSecretReference,\n toEnvSecretReference,\n extractEnvSecretName,\n MissingEnvSecretError,\n} from './secret-resolver';\n\n// Type re-export — the credentials struct itself lives in the ADCP core types\n// module alongside `AgentOAuthTokens` / `AgentOAuthClient`.\nexport type { AgentOAuthClientCredentials } from '../../types/adcp';\n\n// Per-agent storage binding — the bridge that lets `callTool` pick up the\n// caller's chosen `OAuthConfigStorage` without a signature change.\nexport { bindAgentStorage, getAgentStorage, unbindAgentStorage } from './storage-registry';\n\n// Re-exported MCP SDK OAuth error types so consumers can discriminate 401 causes\n// without string-matching on error messages. These originate from the MCP server\n// auth module but are the canonical OAuth error classes for client-side handling too.\nexport { InvalidTokenError, InsufficientScopeError } from '@modelcontextprotocol/sdk/server/auth/errors.js';\n"],"mappings":"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","names":["MCPOAuthProvider","CLIFlowHandler","NonInteractiveFlowHandler","DEFAULT_CLIENT_METADATA"]}
|
|
@@ -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 ENV_PREFIX = "$ENV:";
|
|
8
2
|
class MissingEnvSecretError extends Error {
|
|
9
3
|
constructor(envVar, reason = "unset") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/auth/oauth/secret-resolver.ts"],"sourcesContent":["/**\n * Secret resolution for OAuth client credentials.\n *\n * Values stored in `AgentOAuthClientCredentials.client_id` /\n * `client_secret` may be either literal strings or env-var references in\n * the form `$ENV:VAR_NAME`. Literal secrets end up on disk in\n * `~/.adcp/config.json` (chmod 600); env-var references stay in the config\n * but the secret itself is pulled from the environment at token-exchange\n * time — the CI path where secrets come from the pipeline and should never\n * hit the filesystem.\n *\n * There is no auto-detection: a value without the `$ENV:` prefix is treated\n * as a literal. The CLI's `--client-secret-env VAR` flag writes the\n * reference form.\n */\n\nconst ENV_PREFIX = '$ENV:';\n\n/**\n * Raised when a `$ENV:VAR` reference cannot be resolved. The\n * {@link reason} discriminator separates \"variable not set at all\" from\n * \"set to empty string\" — the latter is a common CI footgun (`.env` with\n * `CLIENT_SECRET=`) that deserves a different nudge to the user.\n */\nexport class MissingEnvSecretError extends Error {\n readonly code = 'missing_env_secret';\n constructor(\n public readonly envVar: string,\n public readonly reason: 'unset' | 'empty' = 'unset'\n ) {\n const detail =\n reason === 'empty'\n ? `is set but empty. Assign a non-empty value to ${envVar} (empty strings are ignored to catch '.env' typos).`\n : `is not set. Export ${envVar} or re-save the agent with a literal secret.`;\n super(`OAuth credential references environment variable '${envVar}' but it ${detail}`);\n this.name = 'MissingEnvSecretError';\n }\n}\n\n/**\n * Resolve a credential value that may be a `$ENV:VAR` reference.\n *\n * - Literal strings pass through unchanged.\n * - `$ENV:VAR` reads `process.env.VAR` and returns it. Throws\n * {@link MissingEnvSecretError} with `reason: 'unset'` if the variable\n * is not set, and `reason: 'empty'` if it is set to the empty string.\n * We treat empty as missing to catch `.env` typos — a compliance run\n * should loudly fail rather than silently POST an empty secret.\n *\n * Whitespace around the variable name (`$ENV: FOO`) is tolerated — a common\n * copy/paste mistake that we don't want to punish at runtime.\n */\nexport function resolveSecret(value: string): string {\n if (!value.startsWith(ENV_PREFIX)) {\n return value;\n }\n const envVar = value.slice(ENV_PREFIX.length).trim();\n if (!envVar) {\n throw new Error(`Invalid OAuth credential reference '${value}': expected '$ENV:VAR_NAME' with a variable name.`);\n }\n const resolved = process.env[envVar];\n if (resolved === undefined) {\n throw new MissingEnvSecretError(envVar, 'unset');\n }\n if (resolved === '') {\n throw new MissingEnvSecretError(envVar, 'empty');\n }\n return resolved;\n}\n\n/** True if `value` is a `$ENV:VAR` reference (not a literal secret). */\nexport function isEnvSecretReference(value: string): boolean {\n return value.startsWith(ENV_PREFIX);\n}\n\n/** Build a `$ENV:VAR` reference string from an env-var name. */\nexport function toEnvSecretReference(envVar: string): string {\n return `${ENV_PREFIX}${envVar}`;\n}\n\n/**\n * Extract the env-var name from a `$ENV:VAR` reference, or `null` if the\n * value is a literal secret. Safe to display: the env-var name is not\n * itself sensitive (it's a well-known identifier the user chose), and this\n * helper exists so callers printing the source of a credential can avoid\n * handling the raw `client_secret` field value at all.\n */\nexport function extractEnvSecretName(value: string): string | null {\n if (!value.startsWith(ENV_PREFIX)) return null;\n const envVar = value.slice(ENV_PREFIX.length).trim();\n return envVar || null;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/auth/oauth/secret-resolver.ts"],"sourcesContent":["/**\n * Secret resolution for OAuth client credentials.\n *\n * Values stored in `AgentOAuthClientCredentials.client_id` /\n * `client_secret` may be either literal strings or env-var references in\n * the form `$ENV:VAR_NAME`. Literal secrets end up on disk in\n * `~/.adcp/config.json` (chmod 600); env-var references stay in the config\n * but the secret itself is pulled from the environment at token-exchange\n * time — the CI path where secrets come from the pipeline and should never\n * hit the filesystem.\n *\n * There is no auto-detection: a value without the `$ENV:` prefix is treated\n * as a literal. The CLI's `--client-secret-env VAR` flag writes the\n * reference form.\n */\n\nconst ENV_PREFIX = '$ENV:';\n\n/**\n * Raised when a `$ENV:VAR` reference cannot be resolved. The\n * {@link reason} discriminator separates \"variable not set at all\" from\n * \"set to empty string\" — the latter is a common CI footgun (`.env` with\n * `CLIENT_SECRET=`) that deserves a different nudge to the user.\n */\nexport class MissingEnvSecretError extends Error {\n readonly code = 'missing_env_secret';\n constructor(\n public readonly envVar: string,\n public readonly reason: 'unset' | 'empty' = 'unset'\n ) {\n const detail =\n reason === 'empty'\n ? `is set but empty. Assign a non-empty value to ${envVar} (empty strings are ignored to catch '.env' typos).`\n : `is not set. Export ${envVar} or re-save the agent with a literal secret.`;\n super(`OAuth credential references environment variable '${envVar}' but it ${detail}`);\n this.name = 'MissingEnvSecretError';\n }\n}\n\n/**\n * Resolve a credential value that may be a `$ENV:VAR` reference.\n *\n * - Literal strings pass through unchanged.\n * - `$ENV:VAR` reads `process.env.VAR` and returns it. Throws\n * {@link MissingEnvSecretError} with `reason: 'unset'` if the variable\n * is not set, and `reason: 'empty'` if it is set to the empty string.\n * We treat empty as missing to catch `.env` typos — a compliance run\n * should loudly fail rather than silently POST an empty secret.\n *\n * Whitespace around the variable name (`$ENV: FOO`) is tolerated — a common\n * copy/paste mistake that we don't want to punish at runtime.\n */\nexport function resolveSecret(value: string): string {\n if (!value.startsWith(ENV_PREFIX)) {\n return value;\n }\n const envVar = value.slice(ENV_PREFIX.length).trim();\n if (!envVar) {\n throw new Error(`Invalid OAuth credential reference '${value}': expected '$ENV:VAR_NAME' with a variable name.`);\n }\n const resolved = process.env[envVar];\n if (resolved === undefined) {\n throw new MissingEnvSecretError(envVar, 'unset');\n }\n if (resolved === '') {\n throw new MissingEnvSecretError(envVar, 'empty');\n }\n return resolved;\n}\n\n/** True if `value` is a `$ENV:VAR` reference (not a literal secret). */\nexport function isEnvSecretReference(value: string): boolean {\n return value.startsWith(ENV_PREFIX);\n}\n\n/** Build a `$ENV:VAR` reference string from an env-var name. */\nexport function toEnvSecretReference(envVar: string): string {\n return `${ENV_PREFIX}${envVar}`;\n}\n\n/**\n * Extract the env-var name from a `$ENV:VAR` reference, or `null` if the\n * value is a literal secret. Safe to display: the env-var name is not\n * itself sensitive (it's a well-known identifier the user chose), and this\n * helper exists so callers printing the source of a credential can avoid\n * handling the raw `client_secret` field value at all.\n */\nexport function extractEnvSecretName(value: string): string | null {\n if (!value.startsWith(ENV_PREFIX)) return null;\n const envVar = value.slice(ENV_PREFIX.length).trim();\n return envVar || null;\n}\n"],"mappings":"AAgBA,MAAM,aAAa;AAQZ,MAAM,8BAA8B,MAAM;AAAA,EAE/C,YACkB,QACA,SAA4B,SAC5C;AACA,UAAM,SACJ,WAAW,UACP,iDAAiD,MAAM,wDACvD,sBAAsB,MAAM;AAClC,UAAM,qDAAqD,MAAM,YAAY,MAAM,EAAE;AAPrE;AACA;AAOhB,SAAK,OAAO;AAAA,EACd;AAAA,EATkB;AAAA,EACA;AAAA,EAHT,OAAO;AAYlB;AAeO,SAAS,cAAc,OAAuB;AACnD,MAAI,CAAC,MAAM,WAAW,UAAU,GAAG;AACjC,WAAO;AAAA,EACT;AACA,QAAM,SAAS,MAAM,MAAM,WAAW,MAAM,EAAE,KAAK;AACnD,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,uCAAuC,KAAK,mDAAmD;AAAA,EACjH;AACA,QAAM,WAAW,QAAQ,IAAI,MAAM;AACnC,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI,sBAAsB,QAAQ,OAAO;AAAA,EACjD;AACA,MAAI,aAAa,IAAI;AACnB,UAAM,IAAI,sBAAsB,QAAQ,OAAO;AAAA,EACjD;AACA,SAAO;AACT;AAGO,SAAS,qBAAqB,OAAwB;AAC3D,SAAO,MAAM,WAAW,UAAU;AACpC;AAGO,SAAS,qBAAqB,QAAwB;AAC3D,SAAO,GAAG,UAAU,GAAG,MAAM;AAC/B;AASO,SAAS,qBAAqB,OAA8B;AACjE,MAAI,CAAC,MAAM,WAAW,UAAU,EAAG,QAAO;AAC1C,QAAM,SAAS,MAAM,MAAM,WAAW,MAAM,EAAE,KAAK;AACnD,SAAO,UAAU;AACnB;","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 STORAGE_KEY = /* @__PURE__ */ Symbol.for("@adcp/client:oauth-config-storage");
|
|
8
2
|
function bindAgentStorage(agent, storage) {
|
|
9
3
|
agent[STORAGE_KEY] = storage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/auth/oauth/storage-registry.ts"],"sourcesContent":["/**\n * Per-agent OAuth storage binding.\n *\n * `ProtocolClient.callTool` constructs the non-interactive OAuth provider\n * inline from an `AgentConfig`, and needs to attach an `OAuthConfigStorage`\n * implementation when one is available — but only when the caller configured\n * one for that particular agent. Rather than threading storage through every\n * positional parameter of `callTool`, we attach it to the agent via a\n * `Symbol`-keyed enumerable property.\n *\n * Why a symbol and not a `WeakMap` or a string-keyed field:\n *\n * - `{...agent}` spreads copy enumerable string *and* symbol properties, so\n * the binding survives the normalization + discovery passes that\n * `SingleAgentClient` performs before calling `ProtocolClient.callTool`.\n * - `JSON.stringify` ignores symbol keys, so the binding never lands on\n * disk when an agent is persisted.\n * - Using `Symbol.for(…)` (the global registry) keeps the binding readable\n * across module instances — relevant when the library is loaded from both\n * `dist/` and a workspace link during dev-loops.\n */\nimport type { AgentConfig } from '../../types/adcp';\nimport type { OAuthConfigStorage } from './types';\n\nconst STORAGE_KEY = Symbol.for('@adcp/client:oauth-config-storage');\n\n/**\n * Attach an `OAuthConfigStorage` to an `AgentConfig` so that downstream\n * `callTool` invocations pick it up when constructing an OAuth provider.\n *\n * Call this once after resolving the agent (typically in the CLI after\n * loading from `~/.adcp/config.json`, or in a multi-tenant service after\n * looking up the agent record for a request).\n */\nexport function bindAgentStorage(agent: AgentConfig, storage: OAuthConfigStorage): void {\n (agent as unknown as Record<symbol, OAuthConfigStorage>)[STORAGE_KEY] = storage;\n}\n\n/**\n * Read the `OAuthConfigStorage` bound to an `AgentConfig`, or `undefined`\n * if none was bound. Used by the protocol client when wiring the OAuth\n * provider at call time.\n */\nexport function getAgentStorage(agent: AgentConfig): OAuthConfigStorage | undefined {\n return (agent as unknown as Record<symbol, OAuthConfigStorage | undefined>)[STORAGE_KEY];\n}\n\n/**\n * Remove the binding for an agent. Typically not needed (GC handles it) but\n * useful in tests that reuse agent objects across scenarios.\n */\nexport function unbindAgentStorage(agent: AgentConfig): void {\n delete (agent as unknown as Record<symbol, OAuthConfigStorage>)[STORAGE_KEY];\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/auth/oauth/storage-registry.ts"],"sourcesContent":["/**\n * Per-agent OAuth storage binding.\n *\n * `ProtocolClient.callTool` constructs the non-interactive OAuth provider\n * inline from an `AgentConfig`, and needs to attach an `OAuthConfigStorage`\n * implementation when one is available — but only when the caller configured\n * one for that particular agent. Rather than threading storage through every\n * positional parameter of `callTool`, we attach it to the agent via a\n * `Symbol`-keyed enumerable property.\n *\n * Why a symbol and not a `WeakMap` or a string-keyed field:\n *\n * - `{...agent}` spreads copy enumerable string *and* symbol properties, so\n * the binding survives the normalization + discovery passes that\n * `SingleAgentClient` performs before calling `ProtocolClient.callTool`.\n * - `JSON.stringify` ignores symbol keys, so the binding never lands on\n * disk when an agent is persisted.\n * - Using `Symbol.for(…)` (the global registry) keeps the binding readable\n * across module instances — relevant when the library is loaded from both\n * `dist/` and a workspace link during dev-loops.\n */\nimport type { AgentConfig } from '../../types/adcp';\nimport type { OAuthConfigStorage } from './types';\n\nconst STORAGE_KEY = Symbol.for('@adcp/client:oauth-config-storage');\n\n/**\n * Attach an `OAuthConfigStorage` to an `AgentConfig` so that downstream\n * `callTool` invocations pick it up when constructing an OAuth provider.\n *\n * Call this once after resolving the agent (typically in the CLI after\n * loading from `~/.adcp/config.json`, or in a multi-tenant service after\n * looking up the agent record for a request).\n */\nexport function bindAgentStorage(agent: AgentConfig, storage: OAuthConfigStorage): void {\n (agent as unknown as Record<symbol, OAuthConfigStorage>)[STORAGE_KEY] = storage;\n}\n\n/**\n * Read the `OAuthConfigStorage` bound to an `AgentConfig`, or `undefined`\n * if none was bound. Used by the protocol client when wiring the OAuth\n * provider at call time.\n */\nexport function getAgentStorage(agent: AgentConfig): OAuthConfigStorage | undefined {\n return (agent as unknown as Record<symbol, OAuthConfigStorage | undefined>)[STORAGE_KEY];\n}\n\n/**\n * Remove the binding for an agent. Typically not needed (GC handles it) but\n * useful in tests that reuse agent objects across scenarios.\n */\nexport function unbindAgentStorage(agent: AgentConfig): void {\n delete (agent as unknown as Record<symbol, OAuthConfigStorage>)[STORAGE_KEY];\n}\n"],"mappings":"AAwBA,MAAM,cAAc,uBAAO,IAAI,mCAAmC;AAU3D,SAAS,iBAAiB,OAAoB,SAAmC;AACtF,EAAC,MAAwD,WAAW,IAAI;AAC1E;AAOO,SAAS,gBAAgB,OAAoD;AAClF,SAAQ,MAAoE,WAAW;AACzF;AAMO,SAAS,mBAAmB,OAA0B;AAC3D,SAAQ,MAAwD,WAAW;AAC7E;","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_CLIENT_METADATA = {
|
|
8
2
|
client_name: "ADCP Client",
|
|
9
3
|
redirect_uris: ["http://localhost:8766/callback"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/auth/oauth/types.ts"],"sourcesContent":["/**\n * OAuth types for MCP authentication\n *\n * These types support the pluggable OAuth architecture:\n * - OAuthConfigStorage: Interface for reading/writing agent config with OAuth data\n * - OAuthFlowHandler: Abstract interface for authorization flow (CLI vs web)\n */\n\nimport type {\n OAuthClientInformation,\n OAuthClientInformationFull,\n OAuthClientMetadata,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/shared/auth.js';\nimport type { AgentConfig, AgentOAuthTokens, AgentOAuthClient } from '../../types/adcp';\n\n// Re-export MCP SDK types for convenience\nexport type { OAuthClientInformation, OAuthClientInformationFull, OAuthClientMetadata, OAuthTokens };\n\n// Re-export agent types\nexport type { AgentConfig, AgentOAuthTokens, AgentOAuthClient };\n\n/**\n * Agent config storage interface\n *\n * Implement this to persist OAuth tokens back to agent configuration.\n * This allows different storage backends (file, database, memory)\n * while keeping tokens in the agent config structure.\n */\nexport interface OAuthConfigStorage {\n /**\n * Load agent configuration\n * @param agentId The agent ID\n * @returns Agent config or undefined if not found\n */\n loadAgent(agentId: string): Promise<AgentConfig | undefined>;\n\n /**\n * Save agent configuration (with updated OAuth data)\n * @param agent The agent config to save\n */\n saveAgent(agent: AgentConfig): Promise<void>;\n}\n\n/**\n * Authorization flow handler - implement this for different environments\n *\n * Examples:\n * - CLIFlowHandler: Opens browser, starts callback server\n * - WebFlowHandler: HTTP redirects\n * - HeadlessFlowHandler: Device code flow (future)\n */\nexport interface OAuthFlowHandler {\n /**\n * Get the callback URL for OAuth redirects\n */\n getRedirectUrl(): string | URL;\n\n /**\n * Redirect the user to the authorization URL\n * For CLI: Opens browser\n * For web: HTTP redirect or return URL for client-side redirect\n *\n * @param authorizationUrl The OAuth authorization URL\n * @returns Promise that resolves when user is redirected\n */\n redirectToAuthorization(authorizationUrl: URL): Promise<void>;\n\n /**\n * Wait for the authorization callback and extract the auth code\n * For CLI: Starts a local HTTP server and waits\n * For web: Called by the callback route handler\n *\n * @returns Promise resolving to the authorization code\n */\n waitForCallback(): Promise<string>;\n\n /**\n * Clean up any resources (e.g., callback server)\n */\n cleanup(): Promise<void>;\n}\n\n/**\n * Configuration for creating an OAuth provider\n */\nexport interface OAuthProviderConfig {\n /** Agent configuration (tokens will be stored here) */\n agent: AgentConfig;\n\n /** Storage for persisting agent config changes */\n storage?: OAuthConfigStorage;\n\n /** Authorization flow handler */\n flowHandler: OAuthFlowHandler;\n\n /** OAuth client metadata (required - use DEFAULT_CLIENT_METADATA as base) */\n clientMetadata: OAuthClientMetadata;\n\n /**\n * Allow non-HTTPS resource URLs in RFC 9728 protected-resource metadata.\n * Mirrors the CLI's `--allow-http` flag and matches the operator-driven\n * trust model used elsewhere in the SDK (`ssrfSafeFetch.allowPrivateIp`,\n * the agent-entry URL validators). Defaults to `false`.\n *\n * Scope: relaxes only the HTTPS-only check on the PRM `resource` value.\n * Does NOT widen network-layer SSRF posture (that knob is\n * `ADCP_ALLOW_INTERNAL_PROBES` at module load, fed by the CLI). Intended\n * for local dev loops; do not enable when talking to remote authorization\n * servers — the AS remains the audience gatekeeper, but a non-HTTPS\n * resource URL implies the transport itself is unauthenticated.\n */\n allowHttp?: boolean;\n}\n\n/**\n * Default OAuth client metadata for ADCP clients\n */\nexport const DEFAULT_CLIENT_METADATA: OAuthClientMetadata = {\n client_name: 'ADCP Client',\n redirect_uris: ['http://localhost:8766/callback'],\n grant_types: ['authorization_code', 'refresh_token'],\n response_types: ['code'],\n token_endpoint_auth_method: 'none', // Public client (no client_secret)\n};\n\n/**\n * OAuth error types\n */\nexport class OAuthError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly agentId?: string\n ) {\n super(message);\n this.name = 'OAuthError';\n }\n}\n\nexport class OAuthCancelledError extends OAuthError {\n constructor(agentId?: string) {\n super('OAuth flow was cancelled by user', 'cancelled', agentId);\n this.name = 'OAuthCancelledError';\n }\n}\n\nexport class OAuthTimeoutError extends OAuthError {\n constructor(agentId?: string, timeoutMs?: number) {\n super(`OAuth flow timed out${timeoutMs ? ` after ${timeoutMs}ms` : ''}`, 'timeout', agentId);\n this.name = 'OAuthTimeoutError';\n }\n}\n\n/**\n * Convert AgentOAuthTokens to MCP SDK OAuthTokens format\n */\nexport function toMCPTokens(tokens: AgentOAuthTokens): OAuthTokens {\n return {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n token_type: tokens.token_type || 'Bearer',\n expires_in: tokens.expires_in,\n scope: tokens.scope,\n };\n}\n\n/**\n * Convert MCP SDK OAuthTokens to AgentOAuthTokens format\n */\nexport function fromMCPTokens(tokens: OAuthTokens): AgentOAuthTokens {\n const result: AgentOAuthTokens = {\n access_token: tokens.access_token,\n token_type: tokens.token_type,\n scope: tokens.scope,\n };\n\n if (tokens.refresh_token) {\n result.refresh_token = tokens.refresh_token;\n }\n\n if (tokens.expires_in) {\n result.expires_in = tokens.expires_in;\n // Calculate expiration timestamp\n result.expires_at = new Date(Date.now() + tokens.expires_in * 1000).toISOString();\n }\n\n return result;\n}\n\n/**\n * Convert AgentOAuthClient to MCP SDK OAuthClientInformation format\n */\nexport function toMCPClientInfo(client: AgentOAuthClient): OAuthClientInformation {\n return {\n client_id: client.client_id,\n client_secret: client.client_secret,\n client_secret_expires_at: client.client_secret_expires_at,\n };\n}\n\n/**\n * Convert MCP SDK OAuthClientInformationFull to AgentOAuthClient format\n */\nexport function fromMCPClientInfo(info: OAuthClientInformationFull): AgentOAuthClient {\n return {\n client_id: info.client_id,\n client_secret: info.client_secret,\n client_secret_expires_at: info.client_secret_expires_at,\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/auth/oauth/types.ts"],"sourcesContent":["/**\n * OAuth types for MCP authentication\n *\n * These types support the pluggable OAuth architecture:\n * - OAuthConfigStorage: Interface for reading/writing agent config with OAuth data\n * - OAuthFlowHandler: Abstract interface for authorization flow (CLI vs web)\n */\n\nimport type {\n OAuthClientInformation,\n OAuthClientInformationFull,\n OAuthClientMetadata,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/shared/auth.js';\nimport type { AgentConfig, AgentOAuthTokens, AgentOAuthClient } from '../../types/adcp';\n\n// Re-export MCP SDK types for convenience\nexport type { OAuthClientInformation, OAuthClientInformationFull, OAuthClientMetadata, OAuthTokens };\n\n// Re-export agent types\nexport type { AgentConfig, AgentOAuthTokens, AgentOAuthClient };\n\n/**\n * Agent config storage interface\n *\n * Implement this to persist OAuth tokens back to agent configuration.\n * This allows different storage backends (file, database, memory)\n * while keeping tokens in the agent config structure.\n */\nexport interface OAuthConfigStorage {\n /**\n * Load agent configuration\n * @param agentId The agent ID\n * @returns Agent config or undefined if not found\n */\n loadAgent(agentId: string): Promise<AgentConfig | undefined>;\n\n /**\n * Save agent configuration (with updated OAuth data)\n * @param agent The agent config to save\n */\n saveAgent(agent: AgentConfig): Promise<void>;\n}\n\n/**\n * Authorization flow handler - implement this for different environments\n *\n * Examples:\n * - CLIFlowHandler: Opens browser, starts callback server\n * - WebFlowHandler: HTTP redirects\n * - HeadlessFlowHandler: Device code flow (future)\n */\nexport interface OAuthFlowHandler {\n /**\n * Get the callback URL for OAuth redirects\n */\n getRedirectUrl(): string | URL;\n\n /**\n * Redirect the user to the authorization URL\n * For CLI: Opens browser\n * For web: HTTP redirect or return URL for client-side redirect\n *\n * @param authorizationUrl The OAuth authorization URL\n * @returns Promise that resolves when user is redirected\n */\n redirectToAuthorization(authorizationUrl: URL): Promise<void>;\n\n /**\n * Wait for the authorization callback and extract the auth code\n * For CLI: Starts a local HTTP server and waits\n * For web: Called by the callback route handler\n *\n * @returns Promise resolving to the authorization code\n */\n waitForCallback(): Promise<string>;\n\n /**\n * Clean up any resources (e.g., callback server)\n */\n cleanup(): Promise<void>;\n}\n\n/**\n * Configuration for creating an OAuth provider\n */\nexport interface OAuthProviderConfig {\n /** Agent configuration (tokens will be stored here) */\n agent: AgentConfig;\n\n /** Storage for persisting agent config changes */\n storage?: OAuthConfigStorage;\n\n /** Authorization flow handler */\n flowHandler: OAuthFlowHandler;\n\n /** OAuth client metadata (required - use DEFAULT_CLIENT_METADATA as base) */\n clientMetadata: OAuthClientMetadata;\n\n /**\n * Allow non-HTTPS resource URLs in RFC 9728 protected-resource metadata.\n * Mirrors the CLI's `--allow-http` flag and matches the operator-driven\n * trust model used elsewhere in the SDK (`ssrfSafeFetch.allowPrivateIp`,\n * the agent-entry URL validators). Defaults to `false`.\n *\n * Scope: relaxes only the HTTPS-only check on the PRM `resource` value.\n * Does NOT widen network-layer SSRF posture (that knob is\n * `ADCP_ALLOW_INTERNAL_PROBES` at module load, fed by the CLI). Intended\n * for local dev loops; do not enable when talking to remote authorization\n * servers — the AS remains the audience gatekeeper, but a non-HTTPS\n * resource URL implies the transport itself is unauthenticated.\n */\n allowHttp?: boolean;\n}\n\n/**\n * Default OAuth client metadata for ADCP clients\n */\nexport const DEFAULT_CLIENT_METADATA: OAuthClientMetadata = {\n client_name: 'ADCP Client',\n redirect_uris: ['http://localhost:8766/callback'],\n grant_types: ['authorization_code', 'refresh_token'],\n response_types: ['code'],\n token_endpoint_auth_method: 'none', // Public client (no client_secret)\n};\n\n/**\n * OAuth error types\n */\nexport class OAuthError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly agentId?: string\n ) {\n super(message);\n this.name = 'OAuthError';\n }\n}\n\nexport class OAuthCancelledError extends OAuthError {\n constructor(agentId?: string) {\n super('OAuth flow was cancelled by user', 'cancelled', agentId);\n this.name = 'OAuthCancelledError';\n }\n}\n\nexport class OAuthTimeoutError extends OAuthError {\n constructor(agentId?: string, timeoutMs?: number) {\n super(`OAuth flow timed out${timeoutMs ? ` after ${timeoutMs}ms` : ''}`, 'timeout', agentId);\n this.name = 'OAuthTimeoutError';\n }\n}\n\n/**\n * Convert AgentOAuthTokens to MCP SDK OAuthTokens format\n */\nexport function toMCPTokens(tokens: AgentOAuthTokens): OAuthTokens {\n return {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n token_type: tokens.token_type || 'Bearer',\n expires_in: tokens.expires_in,\n scope: tokens.scope,\n };\n}\n\n/**\n * Convert MCP SDK OAuthTokens to AgentOAuthTokens format\n */\nexport function fromMCPTokens(tokens: OAuthTokens): AgentOAuthTokens {\n const result: AgentOAuthTokens = {\n access_token: tokens.access_token,\n token_type: tokens.token_type,\n scope: tokens.scope,\n };\n\n if (tokens.refresh_token) {\n result.refresh_token = tokens.refresh_token;\n }\n\n if (tokens.expires_in) {\n result.expires_in = tokens.expires_in;\n // Calculate expiration timestamp\n result.expires_at = new Date(Date.now() + tokens.expires_in * 1000).toISOString();\n }\n\n return result;\n}\n\n/**\n * Convert AgentOAuthClient to MCP SDK OAuthClientInformation format\n */\nexport function toMCPClientInfo(client: AgentOAuthClient): OAuthClientInformation {\n return {\n client_id: client.client_id,\n client_secret: client.client_secret,\n client_secret_expires_at: client.client_secret_expires_at,\n };\n}\n\n/**\n * Convert MCP SDK OAuthClientInformationFull to AgentOAuthClient format\n */\nexport function fromMCPClientInfo(info: OAuthClientInformationFull): AgentOAuthClient {\n return {\n client_id: info.client_id,\n client_secret: info.client_secret,\n client_secret_expires_at: info.client_secret_expires_at,\n };\n}\n"],"mappings":"AAsHO,MAAM,0BAA+C;AAAA,EAC1D,aAAa;AAAA,EACb,eAAe,CAAC,gCAAgC;AAAA,EAChD,aAAa,CAAC,sBAAsB,eAAe;AAAA,EACnD,gBAAgB,CAAC,MAAM;AAAA,EACvB,4BAA4B;AAAA;AAC9B;AAKO,MAAM,mBAAmB,MAAM;AAAA,EACpC,YACE,SACgB,MACA,SAChB;AACA,UAAM,OAAO;AAHG;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAAA,EACA;AAKpB;AAEO,MAAM,4BAA4B,WAAW;AAAA,EAClD,YAAY,SAAkB;AAC5B,UAAM,oCAAoC,aAAa,OAAO;AAC9D,SAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAM,0BAA0B,WAAW;AAAA,EAChD,YAAY,SAAkB,WAAoB;AAChD,UAAM,uBAAuB,YAAY,UAAU,SAAS,OAAO,EAAE,IAAI,WAAW,OAAO;AAC3F,SAAK,OAAO;AAAA,EACd;AACF;AAKO,SAAS,YAAY,QAAuC;AACjE,SAAO;AAAA,IACL,cAAc,OAAO;AAAA,IACrB,eAAe,OAAO;AAAA,IACtB,YAAY,OAAO,cAAc;AAAA,IACjC,YAAY,OAAO;AAAA,IACnB,OAAO,OAAO;AAAA,EAChB;AACF;AAKO,SAAS,cAAc,QAAuC;AACnE,QAAM,SAA2B;AAAA,IAC/B,cAAc,OAAO;AAAA,IACrB,YAAY,OAAO;AAAA,IACnB,OAAO,OAAO;AAAA,EAChB;AAEA,MAAI,OAAO,eAAe;AACxB,WAAO,gBAAgB,OAAO;AAAA,EAChC;AAEA,MAAI,OAAO,YAAY;AACrB,WAAO,aAAa,OAAO;AAE3B,WAAO,aAAa,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,aAAa,GAAI,EAAE,YAAY;AAAA,EAClF;AAEA,SAAO;AACT;AAKO,SAAS,gBAAgB,QAAkD;AAChF,SAAO;AAAA,IACL,WAAW,OAAO;AAAA,IAClB,eAAe,OAAO;AAAA,IACtB,0BAA0B,OAAO;AAAA,EACnC;AACF;AAKO,SAAS,kBAAkB,MAAoD;AACpF,SAAO;AAAA,IACL,WAAW,KAAK;AAAA,IAChB,eAAe,KAAK;AAAA,IACpB,0BAA0B,KAAK;AAAA,EACjC;AACF;","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 { randomBytes } from "crypto";
|
|
8
2
|
import {
|
|
9
3
|
discoverAuthorizationServerMetadata,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/auth/oauth/web-flow.ts"],"sourcesContent":["/**\n * Web (server-side) OAuth flow helpers for `@adcp/sdk`.\n *\n * Companion to `CLIFlowHandler` for environments where `/oauth/start` and\n * `/oauth/callback` may be served by different processes. Discovery, PKCE,\n * URL construction, and token exchange are delegated to the MCP SDK's\n * `client/auth.js` primitives so this module is glue plus a pending-flow\n * store interface — not reimplemented protocol logic.\n *\n * Wire contract:\n * - PRM (RFC 9728) is consulted first; `prm.resource` is the source of\n * truth for the RFC 8707 `resource` indicator. We fall back to\n * `resourceUrlFromServerUrl(agent.agent_uri)` only when the resource\n * server does not implement PRM (404). Connection / parse / 5xx\n * errors throw `ProtectedResourceMetadataError` — never silently\n * downgrade to local guessing.\n * - `prm.resource` must share an origin with the agent URL; the MCP\n * SDK's `checkResourceAllowed` guards against a poisoned PRM\n * pointing the audience at a third party.\n * - AS URL = `prm.authorization_servers[0]` when PRM is present, else\n * the agent origin.\n * - Scope priority: caller-supplied `scopeHint` (e.g. from a 401\n * `WWW-Authenticate` challenge, per SEP-835) > `prm.scopes_supported`\n * > `clientMetadata.scope`.\n * - Refresh is NOT this module's concern. Once `oauth_tokens` are\n * persisted, `MCPOAuthProvider` handles refresh on the next agent\n * call and the MCP SDK forwards `resource` into the refresh request.\n * Callers who DIY refresh against `oauth_tokens` are responsible for\n * forwarding `resource` themselves.\n */\n\nimport { randomBytes } from 'crypto';\nimport {\n discoverAuthorizationServerMetadata,\n discoverOAuthProtectedResourceMetadata,\n exchangeAuthorization,\n registerClient,\n startAuthorization,\n} from '@modelcontextprotocol/sdk/client/auth.js';\nimport { checkResourceAllowed, resourceUrlFromServerUrl } from '@modelcontextprotocol/sdk/shared/auth-utils.js';\nimport type {\n AuthorizationServerMetadata,\n OAuthClientInformation,\n OAuthClientInformationFull,\n OAuthClientMetadata,\n OAuthProtectedResourceMetadata,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/shared/auth.js';\n\nimport type { AgentConfig, OAuthConfigStorage } from './types';\nimport { DEFAULT_CLIENT_METADATA, fromMCPClientInfo, fromMCPTokens, OAuthError, toMCPClientInfo } from './types';\n\n/**\n * Default TTL for a pending web flow row. RFC 6749 §10.12 recommends\n * short-lived state; 10 minutes covers slow-typing users without leaving\n * the PKCE verifier on disk longer than necessary.\n */\nexport const DEFAULT_WEB_FLOW_TTL_MS = 10 * 60 * 1000;\n\n/**\n * State persisted between `/oauth/start` and `/oauth/callback`.\n *\n * `codeVerifier` is a PKCE secret. Store implementations MUST encrypt it\n * at rest if persistence crosses a trust boundary (shared DB, cross-tenant\n * Redis, etc.).\n *\n * `carry` is preserved verbatim and round-tripped to the callback. It\n * MUST be JSON-serializable, MUST NOT contain secrets, and MUST be\n * treated as attacker-influenced data (the caller typically populates it\n * from the `/start` request).\n */\nexport interface PendingWebFlow {\n state: string;\n agentId: string;\n agentUrl: string;\n codeVerifier: string;\n redirectUri: string;\n resource?: string;\n scope?: string;\n authorizationServerUrl: string;\n /** Persist as JSON (e.g. Postgres `jsonb`); contents are MCP SDK-typed. */\n clientInformation: OAuthClientInformation;\n createdAt: Date;\n expiresAt: Date;\n /** JSON-serializable, no secrets, attacker-influenced. */\n carry?: Record<string, unknown>;\n}\n\n/**\n * Persistence interface for in-flight web OAuth flows.\n *\n * Canonical implementations:\n *\n * Postgres:\n * ```sql\n * INSERT INTO pending_oauth_flows (state, payload, expires_at)\n * VALUES ($1, $2, $3);\n * -- consume:\n * DELETE FROM pending_oauth_flows\n * WHERE state = $1 AND expires_at > now()\n * RETURNING payload;\n * ```\n *\n * Redis:\n * ```\n * SET pending:flow:<state> <payload> EX 600 NX -- put\n * GETDEL pending:flow:<state> -- consume\n * ```\n *\n * `consume` MUST be a single atomic operation that deletes and returns the\n * row (or returns null). A `SELECT` followed by a separate `DELETE` is a\n * replay vulnerability and DOES NOT satisfy this contract — a callback\n * replayed before the first one commits would mint two tokens.\n *\n * `consume` MUST treat expired rows as absent (return null) and SHOULD\n * delete them on read so a separate sweep is not strictly required.\n *\n * **Tradeoff: consume runs before token exchange.** `completeWebOAuthFlow`\n * consumes the pending row before attempting `exchangeAuthorization`. If\n * the AS returns a transient 5xx (or the network blips between us and the\n * AS), the row is gone and the user must restart from `/oauth/start`.\n * This is the right call for `invalid_grant` (replay protection — the\n * authorization code is one-shot at the AS regardless), but it means\n * transient AS failures cost the user a click. Revisit only if you see\n * real retry-loss in the field.\n */\nexport interface PendingWebFlowStore {\n /** Insert a new flow. MUST reject duplicate `state`. */\n put(flow: PendingWebFlow): Promise<void>;\n /**\n * Atomic delete-and-return. MUST NOT return the same row twice.\n * Returns null if the row is absent or expired.\n */\n consume(state: string): Promise<PendingWebFlow | null>;\n /** Optional housekeeping for expired rows that were never claimed. */\n cleanupExpired?(): Promise<number>;\n}\n\n/** @deprecated Renamed to `PendingWebFlowStore`. */\nexport type PendingFlowStore = PendingWebFlowStore;\n\nexport class InvalidOrExpiredFlowError extends OAuthError {\n constructor(state: string) {\n super(`OAuth flow not found or expired (state=${state})`, 'invalid_or_expired_flow');\n this.name = 'InvalidOrExpiredFlowError';\n }\n}\n\nexport class StateMismatchError extends OAuthError {\n constructor() {\n super('OAuth state does not match the value the caller bound to this session', 'state_mismatch');\n this.name = 'StateMismatchError';\n }\n}\n\nexport class TokenExchangeError extends OAuthError {\n constructor(\n message: string,\n public readonly status: number,\n public readonly body: string,\n /**\n * RFC 6749 §5.2 error code when the authorization server returned a\n * standard error envelope (`invalid_grant`, `invalid_client`, etc.).\n * Undefined when the AS returned a non-OAuth-shaped failure.\n */\n public readonly oauthErrorCode?: string\n ) {\n super(message, 'token_exchange_failed');\n this.name = 'TokenExchangeError';\n }\n}\n\nexport class ProtectedResourceMetadataError extends OAuthError {\n constructor(message: string) {\n super(message, 'protected_resource_metadata_error');\n this.name = 'ProtectedResourceMetadataError';\n }\n}\n\nexport class AgentVanishedDuringFlowError extends OAuthError {\n constructor(agentId: string) {\n super(\n `Agent ${agentId} could not be loaded from storage during token persistence; tokens were not saved`,\n 'agent_vanished_during_flow',\n agentId\n );\n this.name = 'AgentVanishedDuringFlowError';\n }\n}\n\nexport class ConfidentialClientNotAllowedError extends OAuthError {\n constructor(agentId: string | undefined) {\n super(\n 'Authorization server issued a confidential client (client_secret) during dynamic registration. ' +\n 'Pass `allowConfidentialClient: true` if you intend to persist a long-lived AS credential to your agent storage.',\n 'confidential_client_not_allowed',\n agentId\n );\n this.name = 'ConfidentialClientNotAllowedError';\n }\n}\n\nexport interface StartWebFlowOptions {\n /** Agent the flow is for. Must include `agent_uri`. */\n agent: AgentConfig;\n /** Absolute URL of the consumer's `/callback` route (must match what the AS sees). */\n redirectUri: string;\n /** Where to persist the pending flow until callback. */\n pendingFlowStore: PendingWebFlowStore;\n /** When provided, dynamic-registration results land in `agent.oauth_client`. */\n agentStorage?: OAuthConfigStorage;\n /**\n * Free-form caller payload, round-tripped to `completeWebOAuthFlow`.\n * Must be JSON-serializable. Do not store secrets here. Treated as\n * attacker-influenced — validate before reflecting (e.g. via\n * {@link safeReturnTo} for redirect targets).\n */\n carry?: Record<string, unknown>;\n /**\n * Scope hint (highest priority per SEP-835). Pass through the `scope`\n * value from a prior 401 `WWW-Authenticate` challenge if you have one.\n */\n scopeHint?: string;\n /** Override flow TTL. Default: {@link DEFAULT_WEB_FLOW_TTL_MS}. */\n ttlMs?: number;\n /** Override the random-state generator (defaults to 32 bytes base64url). */\n generateState?: () => string;\n /** Override `fetch` (timeouts, signing, mocks). */\n fetch?: typeof fetch;\n /**\n * Override base client metadata. `redirect_uris` is always replaced\n * with `[redirectUri]` regardless of what's passed here.\n */\n clientMetadata?: Partial<OAuthClientMetadata>;\n /**\n * Permit the AS to register a confidential client (i.e. one that\n * returns a `client_secret` from dynamic registration). Default false:\n * if the AS issues a secret we throw {@link ConfidentialClientNotAllowedError}\n * rather than silently persisting a long-lived credential to your\n * agent storage.\n */\n allowConfidentialClient?: boolean;\n}\n\nexport interface StartWebFlowResult {\n authorizationUrl: string;\n state: string;\n expiresAt: Date;\n}\n\nexport interface CompleteWebFlowOptions {\n state: string;\n code: string;\n pendingFlowStore: PendingWebFlowStore;\n /** When provided, the issued tokens are persisted to `agent.oauth_tokens`. */\n agentStorage?: OAuthConfigStorage;\n fetch?: typeof fetch;\n /**\n * The caller-bound expected state (e.g. from a session cookie set at\n * `/oauth/start`). When provided, must equal `state`; mismatch throws\n * {@link StateMismatchError}. Without this, `state` is replay-protected\n * but not browser-bound — see WEB-OAUTH.md.\n */\n expectedState?: string;\n}\n\nexport interface CompleteWebFlowResult {\n agentId: string;\n agentUrl: string;\n tokens: OAuthTokens;\n carry?: Record<string, unknown>;\n /** True if `agentStorage` was provided AND `saveAgent` succeeded. */\n persisted: boolean;\n}\n\n/**\n * Begin a web OAuth flow. Returns the authorization URL the consumer\n * should redirect the browser to. Persists the PKCE verifier and other\n * flow state via `pendingFlowStore.put` so a different process can complete it.\n */\nexport async function startWebOAuthFlow(opts: StartWebFlowOptions): Promise<StartWebFlowResult> {\n const {\n agent,\n redirectUri,\n pendingFlowStore,\n agentStorage,\n carry,\n scopeHint,\n ttlMs = DEFAULT_WEB_FLOW_TTL_MS,\n generateState,\n fetch: fetchFn,\n clientMetadata: clientMetadataOverrides,\n allowConfidentialClient = false,\n } = opts;\n\n if (!agent.agent_uri) {\n throw new OAuthError('Agent missing agent_uri', 'invalid_agent', agent.id);\n }\n\n const prm = await tryDiscoverPRM(agent.agent_uri, fetchFn);\n if (prm?.resource) {\n assertPrmResourceMatchesAgentOrigin(agent.agent_uri, prm.resource);\n }\n\n const asUrl = resolveAuthorizationServerUrl(agent.agent_uri, prm);\n\n const asMetadata = await discoverAuthorizationServerMetadata(asUrl.toString(), { fetchFn });\n if (!asMetadata) {\n throw new OAuthError(`No OAuth metadata at ${asUrl.toString()}`, 'no_authorization_server_metadata', agent.id);\n }\n\n const resource = prm?.resource ? new URL(prm.resource) : resourceUrlFromServerUrl(new URL(agent.agent_uri));\n\n const baseClientMetadata: OAuthClientMetadata = {\n ...DEFAULT_CLIENT_METADATA,\n ...clientMetadataOverrides,\n redirect_uris: [redirectUri],\n };\n\n const scope = scopeHint ?? prm?.scopes_supported?.join(' ') ?? baseClientMetadata.scope;\n\n const clientInformation = await resolveClientInformation({\n agent,\n agentStorage,\n asUrl,\n asMetadata,\n clientMetadata: baseClientMetadata,\n fetchFn,\n allowConfidentialClient,\n });\n\n const state = (generateState ?? defaultGenerateState)();\n const { authorizationUrl, codeVerifier } = await startAuthorization(asUrl.toString(), {\n metadata: asMetadata,\n clientInformation,\n redirectUrl: redirectUri,\n scope,\n state,\n resource,\n });\n\n const now = new Date();\n const expiresAt = new Date(now.getTime() + ttlMs);\n const flow: PendingWebFlow = {\n state,\n agentId: agent.id,\n agentUrl: agent.agent_uri,\n codeVerifier,\n redirectUri,\n resource: resource.href,\n scope,\n authorizationServerUrl: asUrl.toString(),\n clientInformation,\n createdAt: now,\n expiresAt,\n carry,\n };\n await pendingFlowStore.put(flow);\n\n return {\n authorizationUrl: authorizationUrl.toString(),\n state,\n expiresAt,\n };\n}\n\n/**\n * Finish a web OAuth flow. Atomically consumes the pending row, exchanges\n * the authorization code for tokens, and (if storage is provided)\n * persists tokens to `agent.oauth_tokens`. Returns whatever the caller\n * stashed in `carry` so the consumer can route the user appropriately.\n *\n * The pending row is consumed BEFORE `exchangeAuthorization` runs. A\n * transient AS failure leaves the user with no row to retry against and\n * they must restart from `/oauth/start`. See {@link PendingWebFlowStore}\n * for the full tradeoff discussion.\n */\nexport async function completeWebOAuthFlow(opts: CompleteWebFlowOptions): Promise<CompleteWebFlowResult> {\n const { state, code, pendingFlowStore, agentStorage, fetch: fetchFn, expectedState } = opts;\n\n if (expectedState !== undefined && expectedState !== state) {\n throw new StateMismatchError();\n }\n\n const flow = await pendingFlowStore.consume(state);\n if (!flow || flow.expiresAt.getTime() < Date.now()) {\n throw new InvalidOrExpiredFlowError(state);\n }\n\n const asMetadata = await discoverAuthorizationServerMetadata(flow.authorizationServerUrl, {\n fetchFn,\n });\n\n let tokens: OAuthTokens;\n try {\n tokens = await exchangeAuthorization(flow.authorizationServerUrl, {\n metadata: asMetadata ?? undefined,\n clientInformation: flow.clientInformation,\n authorizationCode: code,\n codeVerifier: flow.codeVerifier,\n redirectUri: flow.redirectUri,\n resource: flow.resource ? new URL(flow.resource) : undefined,\n fetchFn,\n });\n } catch (err) {\n throw wrapTokenExchangeError(err);\n }\n\n let persisted = false;\n if (agentStorage) {\n const agent = await agentStorage.loadAgent(flow.agentId);\n if (!agent) {\n throw new AgentVanishedDuringFlowError(flow.agentId);\n }\n agent.oauth_tokens = fromMCPTokens(tokens);\n delete agent.oauth_code_verifier;\n await agentStorage.saveAgent(agent);\n persisted = true;\n }\n\n return {\n agentId: flow.agentId,\n agentUrl: flow.agentUrl,\n tokens,\n carry: flow.carry,\n persisted,\n };\n}\n\n/**\n * Validate a redirect target supplied via `carry`.\n *\n * Treats `value` as attacker-influenced. Returns a string that is safe to\n * pass to `res.redirect`, or `undefined` if the value is invalid.\n *\n * Defaults to **path-only** redirects (must start with a single `/` and\n * not be protocol-relative `//evil.example`). Pass `allowedReturnHosts`\n * to permit absolute URLs against an allowlist.\n *\n * @example\n * ```ts\n * res.redirect(safeReturnTo(carry?.return_to) ?? '/');\n * res.redirect(safeReturnTo(carry?.return_to, { allowedReturnHosts: ['app.example.com'] }) ?? '/');\n * ```\n */\nexport function safeReturnTo(value: unknown, options: { allowedReturnHosts?: string[] } = {}): string | undefined {\n if (typeof value !== 'string' || value.length === 0) return undefined;\n\n // Path-only: must be `/...` but not `//...` (protocol-relative) or `/\\...`.\n if (value.startsWith('/') && !value.startsWith('//') && !value.startsWith('/\\\\')) {\n return value;\n }\n\n const allowed = options.allowedReturnHosts;\n if (!allowed || allowed.length === 0) return undefined;\n\n let parsed: URL;\n try {\n parsed = new URL(value);\n } catch {\n return undefined;\n }\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') return undefined;\n if (!allowed.includes(parsed.host)) return undefined;\n return parsed.toString();\n}\n\n/**\n * In-memory pending-flow store for tests and single-instance dev.\n *\n * Production deployments MUST implement `PendingWebFlowStore` against a\n * shared store (Postgres `DELETE … RETURNING`, Redis `GETDEL`) so\n * `/start` and `/callback` can hit different processes.\n */\nexport class InMemoryPendingFlowStore implements PendingWebFlowStore {\n private readonly flows = new Map<string, PendingWebFlow>();\n\n async put(flow: PendingWebFlow): Promise<void> {\n if (this.flows.has(flow.state)) {\n throw new Error(`Pending flow already exists for state ${flow.state}`);\n }\n this.flows.set(flow.state, flow);\n }\n\n async consume(state: string): Promise<PendingWebFlow | null> {\n const flow = this.flows.get(state);\n if (!flow) return null;\n this.flows.delete(state);\n if (flow.expiresAt.getTime() < Date.now()) return null;\n return flow;\n }\n\n async cleanupExpired(): Promise<number> {\n const now = Date.now();\n let removed = 0;\n for (const [state, flow] of this.flows) {\n if (flow.expiresAt.getTime() < now) {\n this.flows.delete(state);\n removed++;\n }\n }\n return removed;\n }\n}\n\n// ============================================================\n// Internals\n// ============================================================\n\n/**\n * The MCP SDK reports a 404 PRM lookup with this exact message; treat it\n * as \"PRM is genuinely absent\" and fall back. Anything else is a\n * connection, parse, or 5xx error and is allowed to bubble.\n *\n * Source (verified against `@modelcontextprotocol/sdk@1.29.0`):\n * `dist/esm/client/auth.js` → `discoverOAuthProtectedResourceMetadata`\n * throws `new Error(`Resource server does not implement OAuth 2.0 Protected Resource Metadata.`)`\n * when `response.status === 404` (or no response was returned).\n *\n * If a future MCP SDK reword this message, the test\n * \"falls back to server-derived resource on a 404 PRM\" at\n * `test/lib/oauth-web-flow.test.js` will fail — that test calls the real\n * SDK against a 404 fixture and is the canary for this regression.\n */\nconst PRM_ABSENT_MARKER = 'does not implement OAuth 2.0 Protected Resource Metadata';\n\nasync function tryDiscoverPRM(\n agentUrl: string,\n fetchFn: typeof fetch | undefined\n): Promise<OAuthProtectedResourceMetadata | undefined> {\n try {\n return await discoverOAuthProtectedResourceMetadata(agentUrl, undefined, fetchFn);\n } catch (err) {\n if (err instanceof Error && err.message.includes(PRM_ABSENT_MARKER)) {\n // PRM is optional under RFC 9728 — fall back to local resource\n // derivation. Connection/parse/5xx errors fall through.\n return undefined;\n }\n const message = err instanceof Error ? err.message : String(err);\n throw new ProtectedResourceMetadataError(`PRM discovery failed: ${message}`);\n }\n}\n\nfunction assertPrmResourceMatchesAgentOrigin(agentUrl: string, prmResource: string): void {\n const requested = resourceUrlFromServerUrl(new URL(agentUrl));\n if (!checkResourceAllowed({ requestedResource: requested, configuredResource: prmResource })) {\n throw new ProtectedResourceMetadataError(\n `PRM advertises resource ${prmResource} which does not share an origin/path with agent ${agentUrl}`\n );\n }\n}\n\nfunction resolveAuthorizationServerUrl(agentUrl: string, prm: OAuthProtectedResourceMetadata | undefined): URL {\n const first = prm?.authorization_servers?.[0];\n if (first) {\n return new URL(first);\n }\n return new URL(new URL(agentUrl).origin);\n}\n\nasync function resolveClientInformation(args: {\n agent: AgentConfig;\n agentStorage?: OAuthConfigStorage;\n asUrl: URL;\n asMetadata: AuthorizationServerMetadata;\n clientMetadata: OAuthClientMetadata;\n fetchFn?: typeof fetch;\n allowConfidentialClient: boolean;\n}): Promise<OAuthClientInformation> {\n const { agent, agentStorage, asUrl, asMetadata, clientMetadata, fetchFn, allowConfidentialClient } = args;\n\n if (agent.oauth_client) {\n return toMCPClientInfo(agent.oauth_client);\n }\n\n if (!asMetadata.registration_endpoint) {\n throw new OAuthError(\n 'Agent has no oauth_client and authorization server does not advertise dynamic client registration',\n 'no_client_credentials',\n agent.id\n );\n }\n\n const registered: OAuthClientInformationFull = await registerClient(asUrl.toString(), {\n metadata: asMetadata,\n clientMetadata,\n fetchFn,\n });\n\n if (registered.client_secret && !allowConfidentialClient) {\n throw new ConfidentialClientNotAllowedError(agent.id);\n }\n\n if (agentStorage) {\n // Load fresh and save fresh so two concurrent /start calls for the\n // same agentId do not trample each other's `oauth_client` via a\n // shared in-memory reference.\n const fresh = (await agentStorage.loadAgent(agent.id)) ?? agent;\n fresh.oauth_client = fromMCPClientInfo(registered);\n await agentStorage.saveAgent(fresh);\n }\n\n return registered;\n}\n\nfunction defaultGenerateState(): string {\n return randomBytes(32).toString('base64url');\n}\n\n/**\n * Map an MCP SDK token-exchange failure to {@link TokenExchangeError},\n * redacting bearer/refresh tokens that some authorization servers echo\n * back in error responses for debugging.\n */\nfunction wrapTokenExchangeError(err: unknown): TokenExchangeError {\n // The MCP SDK's `parseErrorResponse` decodes a well-formed OAuth error\n // envelope into an `OAuthError` subclass with `errorCode` (e.g.\n // `InvalidGrantError`). Malformed responses come through as\n // `ServerError` with the raw body in `message`, so the redaction pass\n // covers both cases.\n const oauthErrorCode = (err as { errorCode?: string })?.errorCode;\n const message = err instanceof Error ? err.message : String(err);\n const status = (err as { status?: number })?.status ?? 0;\n const rawBody = (err as { body?: string })?.body ?? message;\n const body = redactTokens(rawBody);\n const display = oauthErrorCode ? `${oauthErrorCode}: ${message}` : message;\n return new TokenExchangeError(`Token exchange failed: ${redactTokens(display)}`, status, body, oauthErrorCode);\n}\n\nconst SENSITIVE_TOKEN_KEYS = ['access_token', 'refresh_token', 'id_token', 'token'];\n\n/**\n * Best-effort redaction of bearer/refresh tokens from an AS error body\n * (which may be JSON, form-encoded, or freeform). Adopters MUST still\n * treat `TokenExchangeError.body` as sensitive — do not reflect it to\n * the browser or write it to access logs unredacted.\n */\nfunction redactTokens(input: string): string {\n let out = input;\n for (const key of SENSITIVE_TOKEN_KEYS) {\n // JSON form: \"key\":\"…\"\n out = out.replace(new RegExp(`(\"${key}\"\\\\s*:\\\\s*\")[^\"]*(\")`, 'gi'), '$1<redacted>$2');\n // form-encoded: key=…\n out = out.replace(new RegExp(`(\\\\b${key}=)[^&\\\\s]+`, 'gi'), '$1<redacted>');\n }\n return out;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/auth/oauth/web-flow.ts"],"sourcesContent":["/**\n * Web (server-side) OAuth flow helpers for `@adcp/sdk`.\n *\n * Companion to `CLIFlowHandler` for environments where `/oauth/start` and\n * `/oauth/callback` may be served by different processes. Discovery, PKCE,\n * URL construction, and token exchange are delegated to the MCP SDK's\n * `client/auth.js` primitives so this module is glue plus a pending-flow\n * store interface — not reimplemented protocol logic.\n *\n * Wire contract:\n * - PRM (RFC 9728) is consulted first; `prm.resource` is the source of\n * truth for the RFC 8707 `resource` indicator. We fall back to\n * `resourceUrlFromServerUrl(agent.agent_uri)` only when the resource\n * server does not implement PRM (404). Connection / parse / 5xx\n * errors throw `ProtectedResourceMetadataError` — never silently\n * downgrade to local guessing.\n * - `prm.resource` must share an origin with the agent URL; the MCP\n * SDK's `checkResourceAllowed` guards against a poisoned PRM\n * pointing the audience at a third party.\n * - AS URL = `prm.authorization_servers[0]` when PRM is present, else\n * the agent origin.\n * - Scope priority: caller-supplied `scopeHint` (e.g. from a 401\n * `WWW-Authenticate` challenge, per SEP-835) > `prm.scopes_supported`\n * > `clientMetadata.scope`.\n * - Refresh is NOT this module's concern. Once `oauth_tokens` are\n * persisted, `MCPOAuthProvider` handles refresh on the next agent\n * call and the MCP SDK forwards `resource` into the refresh request.\n * Callers who DIY refresh against `oauth_tokens` are responsible for\n * forwarding `resource` themselves.\n */\n\nimport { randomBytes } from 'crypto';\nimport {\n discoverAuthorizationServerMetadata,\n discoverOAuthProtectedResourceMetadata,\n exchangeAuthorization,\n registerClient,\n startAuthorization,\n} from '@modelcontextprotocol/sdk/client/auth.js';\nimport { checkResourceAllowed, resourceUrlFromServerUrl } from '@modelcontextprotocol/sdk/shared/auth-utils.js';\nimport type {\n AuthorizationServerMetadata,\n OAuthClientInformation,\n OAuthClientInformationFull,\n OAuthClientMetadata,\n OAuthProtectedResourceMetadata,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/shared/auth.js';\n\nimport type { AgentConfig, OAuthConfigStorage } from './types';\nimport { DEFAULT_CLIENT_METADATA, fromMCPClientInfo, fromMCPTokens, OAuthError, toMCPClientInfo } from './types';\n\n/**\n * Default TTL for a pending web flow row. RFC 6749 §10.12 recommends\n * short-lived state; 10 minutes covers slow-typing users without leaving\n * the PKCE verifier on disk longer than necessary.\n */\nexport const DEFAULT_WEB_FLOW_TTL_MS = 10 * 60 * 1000;\n\n/**\n * State persisted between `/oauth/start` and `/oauth/callback`.\n *\n * `codeVerifier` is a PKCE secret. Store implementations MUST encrypt it\n * at rest if persistence crosses a trust boundary (shared DB, cross-tenant\n * Redis, etc.).\n *\n * `carry` is preserved verbatim and round-tripped to the callback. It\n * MUST be JSON-serializable, MUST NOT contain secrets, and MUST be\n * treated as attacker-influenced data (the caller typically populates it\n * from the `/start` request).\n */\nexport interface PendingWebFlow {\n state: string;\n agentId: string;\n agentUrl: string;\n codeVerifier: string;\n redirectUri: string;\n resource?: string;\n scope?: string;\n authorizationServerUrl: string;\n /** Persist as JSON (e.g. Postgres `jsonb`); contents are MCP SDK-typed. */\n clientInformation: OAuthClientInformation;\n createdAt: Date;\n expiresAt: Date;\n /** JSON-serializable, no secrets, attacker-influenced. */\n carry?: Record<string, unknown>;\n}\n\n/**\n * Persistence interface for in-flight web OAuth flows.\n *\n * Canonical implementations:\n *\n * Postgres:\n * ```sql\n * INSERT INTO pending_oauth_flows (state, payload, expires_at)\n * VALUES ($1, $2, $3);\n * -- consume:\n * DELETE FROM pending_oauth_flows\n * WHERE state = $1 AND expires_at > now()\n * RETURNING payload;\n * ```\n *\n * Redis:\n * ```\n * SET pending:flow:<state> <payload> EX 600 NX -- put\n * GETDEL pending:flow:<state> -- consume\n * ```\n *\n * `consume` MUST be a single atomic operation that deletes and returns the\n * row (or returns null). A `SELECT` followed by a separate `DELETE` is a\n * replay vulnerability and DOES NOT satisfy this contract — a callback\n * replayed before the first one commits would mint two tokens.\n *\n * `consume` MUST treat expired rows as absent (return null) and SHOULD\n * delete them on read so a separate sweep is not strictly required.\n *\n * **Tradeoff: consume runs before token exchange.** `completeWebOAuthFlow`\n * consumes the pending row before attempting `exchangeAuthorization`. If\n * the AS returns a transient 5xx (or the network blips between us and the\n * AS), the row is gone and the user must restart from `/oauth/start`.\n * This is the right call for `invalid_grant` (replay protection — the\n * authorization code is one-shot at the AS regardless), but it means\n * transient AS failures cost the user a click. Revisit only if you see\n * real retry-loss in the field.\n */\nexport interface PendingWebFlowStore {\n /** Insert a new flow. MUST reject duplicate `state`. */\n put(flow: PendingWebFlow): Promise<void>;\n /**\n * Atomic delete-and-return. MUST NOT return the same row twice.\n * Returns null if the row is absent or expired.\n */\n consume(state: string): Promise<PendingWebFlow | null>;\n /** Optional housekeeping for expired rows that were never claimed. */\n cleanupExpired?(): Promise<number>;\n}\n\n/** @deprecated Renamed to `PendingWebFlowStore`. */\nexport type PendingFlowStore = PendingWebFlowStore;\n\nexport class InvalidOrExpiredFlowError extends OAuthError {\n constructor(state: string) {\n super(`OAuth flow not found or expired (state=${state})`, 'invalid_or_expired_flow');\n this.name = 'InvalidOrExpiredFlowError';\n }\n}\n\nexport class StateMismatchError extends OAuthError {\n constructor() {\n super('OAuth state does not match the value the caller bound to this session', 'state_mismatch');\n this.name = 'StateMismatchError';\n }\n}\n\nexport class TokenExchangeError extends OAuthError {\n constructor(\n message: string,\n public readonly status: number,\n public readonly body: string,\n /**\n * RFC 6749 §5.2 error code when the authorization server returned a\n * standard error envelope (`invalid_grant`, `invalid_client`, etc.).\n * Undefined when the AS returned a non-OAuth-shaped failure.\n */\n public readonly oauthErrorCode?: string\n ) {\n super(message, 'token_exchange_failed');\n this.name = 'TokenExchangeError';\n }\n}\n\nexport class ProtectedResourceMetadataError extends OAuthError {\n constructor(message: string) {\n super(message, 'protected_resource_metadata_error');\n this.name = 'ProtectedResourceMetadataError';\n }\n}\n\nexport class AgentVanishedDuringFlowError extends OAuthError {\n constructor(agentId: string) {\n super(\n `Agent ${agentId} could not be loaded from storage during token persistence; tokens were not saved`,\n 'agent_vanished_during_flow',\n agentId\n );\n this.name = 'AgentVanishedDuringFlowError';\n }\n}\n\nexport class ConfidentialClientNotAllowedError extends OAuthError {\n constructor(agentId: string | undefined) {\n super(\n 'Authorization server issued a confidential client (client_secret) during dynamic registration. ' +\n 'Pass `allowConfidentialClient: true` if you intend to persist a long-lived AS credential to your agent storage.',\n 'confidential_client_not_allowed',\n agentId\n );\n this.name = 'ConfidentialClientNotAllowedError';\n }\n}\n\nexport interface StartWebFlowOptions {\n /** Agent the flow is for. Must include `agent_uri`. */\n agent: AgentConfig;\n /** Absolute URL of the consumer's `/callback` route (must match what the AS sees). */\n redirectUri: string;\n /** Where to persist the pending flow until callback. */\n pendingFlowStore: PendingWebFlowStore;\n /** When provided, dynamic-registration results land in `agent.oauth_client`. */\n agentStorage?: OAuthConfigStorage;\n /**\n * Free-form caller payload, round-tripped to `completeWebOAuthFlow`.\n * Must be JSON-serializable. Do not store secrets here. Treated as\n * attacker-influenced — validate before reflecting (e.g. via\n * {@link safeReturnTo} for redirect targets).\n */\n carry?: Record<string, unknown>;\n /**\n * Scope hint (highest priority per SEP-835). Pass through the `scope`\n * value from a prior 401 `WWW-Authenticate` challenge if you have one.\n */\n scopeHint?: string;\n /** Override flow TTL. Default: {@link DEFAULT_WEB_FLOW_TTL_MS}. */\n ttlMs?: number;\n /** Override the random-state generator (defaults to 32 bytes base64url). */\n generateState?: () => string;\n /** Override `fetch` (timeouts, signing, mocks). */\n fetch?: typeof fetch;\n /**\n * Override base client metadata. `redirect_uris` is always replaced\n * with `[redirectUri]` regardless of what's passed here.\n */\n clientMetadata?: Partial<OAuthClientMetadata>;\n /**\n * Permit the AS to register a confidential client (i.e. one that\n * returns a `client_secret` from dynamic registration). Default false:\n * if the AS issues a secret we throw {@link ConfidentialClientNotAllowedError}\n * rather than silently persisting a long-lived credential to your\n * agent storage.\n */\n allowConfidentialClient?: boolean;\n}\n\nexport interface StartWebFlowResult {\n authorizationUrl: string;\n state: string;\n expiresAt: Date;\n}\n\nexport interface CompleteWebFlowOptions {\n state: string;\n code: string;\n pendingFlowStore: PendingWebFlowStore;\n /** When provided, the issued tokens are persisted to `agent.oauth_tokens`. */\n agentStorage?: OAuthConfigStorage;\n fetch?: typeof fetch;\n /**\n * The caller-bound expected state (e.g. from a session cookie set at\n * `/oauth/start`). When provided, must equal `state`; mismatch throws\n * {@link StateMismatchError}. Without this, `state` is replay-protected\n * but not browser-bound — see WEB-OAUTH.md.\n */\n expectedState?: string;\n}\n\nexport interface CompleteWebFlowResult {\n agentId: string;\n agentUrl: string;\n tokens: OAuthTokens;\n carry?: Record<string, unknown>;\n /** True if `agentStorage` was provided AND `saveAgent` succeeded. */\n persisted: boolean;\n}\n\n/**\n * Begin a web OAuth flow. Returns the authorization URL the consumer\n * should redirect the browser to. Persists the PKCE verifier and other\n * flow state via `pendingFlowStore.put` so a different process can complete it.\n */\nexport async function startWebOAuthFlow(opts: StartWebFlowOptions): Promise<StartWebFlowResult> {\n const {\n agent,\n redirectUri,\n pendingFlowStore,\n agentStorage,\n carry,\n scopeHint,\n ttlMs = DEFAULT_WEB_FLOW_TTL_MS,\n generateState,\n fetch: fetchFn,\n clientMetadata: clientMetadataOverrides,\n allowConfidentialClient = false,\n } = opts;\n\n if (!agent.agent_uri) {\n throw new OAuthError('Agent missing agent_uri', 'invalid_agent', agent.id);\n }\n\n const prm = await tryDiscoverPRM(agent.agent_uri, fetchFn);\n if (prm?.resource) {\n assertPrmResourceMatchesAgentOrigin(agent.agent_uri, prm.resource);\n }\n\n const asUrl = resolveAuthorizationServerUrl(agent.agent_uri, prm);\n\n const asMetadata = await discoverAuthorizationServerMetadata(asUrl.toString(), { fetchFn });\n if (!asMetadata) {\n throw new OAuthError(`No OAuth metadata at ${asUrl.toString()}`, 'no_authorization_server_metadata', agent.id);\n }\n\n const resource = prm?.resource ? new URL(prm.resource) : resourceUrlFromServerUrl(new URL(agent.agent_uri));\n\n const baseClientMetadata: OAuthClientMetadata = {\n ...DEFAULT_CLIENT_METADATA,\n ...clientMetadataOverrides,\n redirect_uris: [redirectUri],\n };\n\n const scope = scopeHint ?? prm?.scopes_supported?.join(' ') ?? baseClientMetadata.scope;\n\n const clientInformation = await resolveClientInformation({\n agent,\n agentStorage,\n asUrl,\n asMetadata,\n clientMetadata: baseClientMetadata,\n fetchFn,\n allowConfidentialClient,\n });\n\n const state = (generateState ?? defaultGenerateState)();\n const { authorizationUrl, codeVerifier } = await startAuthorization(asUrl.toString(), {\n metadata: asMetadata,\n clientInformation,\n redirectUrl: redirectUri,\n scope,\n state,\n resource,\n });\n\n const now = new Date();\n const expiresAt = new Date(now.getTime() + ttlMs);\n const flow: PendingWebFlow = {\n state,\n agentId: agent.id,\n agentUrl: agent.agent_uri,\n codeVerifier,\n redirectUri,\n resource: resource.href,\n scope,\n authorizationServerUrl: asUrl.toString(),\n clientInformation,\n createdAt: now,\n expiresAt,\n carry,\n };\n await pendingFlowStore.put(flow);\n\n return {\n authorizationUrl: authorizationUrl.toString(),\n state,\n expiresAt,\n };\n}\n\n/**\n * Finish a web OAuth flow. Atomically consumes the pending row, exchanges\n * the authorization code for tokens, and (if storage is provided)\n * persists tokens to `agent.oauth_tokens`. Returns whatever the caller\n * stashed in `carry` so the consumer can route the user appropriately.\n *\n * The pending row is consumed BEFORE `exchangeAuthorization` runs. A\n * transient AS failure leaves the user with no row to retry against and\n * they must restart from `/oauth/start`. See {@link PendingWebFlowStore}\n * for the full tradeoff discussion.\n */\nexport async function completeWebOAuthFlow(opts: CompleteWebFlowOptions): Promise<CompleteWebFlowResult> {\n const { state, code, pendingFlowStore, agentStorage, fetch: fetchFn, expectedState } = opts;\n\n if (expectedState !== undefined && expectedState !== state) {\n throw new StateMismatchError();\n }\n\n const flow = await pendingFlowStore.consume(state);\n if (!flow || flow.expiresAt.getTime() < Date.now()) {\n throw new InvalidOrExpiredFlowError(state);\n }\n\n const asMetadata = await discoverAuthorizationServerMetadata(flow.authorizationServerUrl, {\n fetchFn,\n });\n\n let tokens: OAuthTokens;\n try {\n tokens = await exchangeAuthorization(flow.authorizationServerUrl, {\n metadata: asMetadata ?? undefined,\n clientInformation: flow.clientInformation,\n authorizationCode: code,\n codeVerifier: flow.codeVerifier,\n redirectUri: flow.redirectUri,\n resource: flow.resource ? new URL(flow.resource) : undefined,\n fetchFn,\n });\n } catch (err) {\n throw wrapTokenExchangeError(err);\n }\n\n let persisted = false;\n if (agentStorage) {\n const agent = await agentStorage.loadAgent(flow.agentId);\n if (!agent) {\n throw new AgentVanishedDuringFlowError(flow.agentId);\n }\n agent.oauth_tokens = fromMCPTokens(tokens);\n delete agent.oauth_code_verifier;\n await agentStorage.saveAgent(agent);\n persisted = true;\n }\n\n return {\n agentId: flow.agentId,\n agentUrl: flow.agentUrl,\n tokens,\n carry: flow.carry,\n persisted,\n };\n}\n\n/**\n * Validate a redirect target supplied via `carry`.\n *\n * Treats `value` as attacker-influenced. Returns a string that is safe to\n * pass to `res.redirect`, or `undefined` if the value is invalid.\n *\n * Defaults to **path-only** redirects (must start with a single `/` and\n * not be protocol-relative `//evil.example`). Pass `allowedReturnHosts`\n * to permit absolute URLs against an allowlist.\n *\n * @example\n * ```ts\n * res.redirect(safeReturnTo(carry?.return_to) ?? '/');\n * res.redirect(safeReturnTo(carry?.return_to, { allowedReturnHosts: ['app.example.com'] }) ?? '/');\n * ```\n */\nexport function safeReturnTo(value: unknown, options: { allowedReturnHosts?: string[] } = {}): string | undefined {\n if (typeof value !== 'string' || value.length === 0) return undefined;\n\n // Path-only: must be `/...` but not `//...` (protocol-relative) or `/\\...`.\n if (value.startsWith('/') && !value.startsWith('//') && !value.startsWith('/\\\\')) {\n return value;\n }\n\n const allowed = options.allowedReturnHosts;\n if (!allowed || allowed.length === 0) return undefined;\n\n let parsed: URL;\n try {\n parsed = new URL(value);\n } catch {\n return undefined;\n }\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') return undefined;\n if (!allowed.includes(parsed.host)) return undefined;\n return parsed.toString();\n}\n\n/**\n * In-memory pending-flow store for tests and single-instance dev.\n *\n * Production deployments MUST implement `PendingWebFlowStore` against a\n * shared store (Postgres `DELETE … RETURNING`, Redis `GETDEL`) so\n * `/start` and `/callback` can hit different processes.\n */\nexport class InMemoryPendingFlowStore implements PendingWebFlowStore {\n private readonly flows = new Map<string, PendingWebFlow>();\n\n async put(flow: PendingWebFlow): Promise<void> {\n if (this.flows.has(flow.state)) {\n throw new Error(`Pending flow already exists for state ${flow.state}`);\n }\n this.flows.set(flow.state, flow);\n }\n\n async consume(state: string): Promise<PendingWebFlow | null> {\n const flow = this.flows.get(state);\n if (!flow) return null;\n this.flows.delete(state);\n if (flow.expiresAt.getTime() < Date.now()) return null;\n return flow;\n }\n\n async cleanupExpired(): Promise<number> {\n const now = Date.now();\n let removed = 0;\n for (const [state, flow] of this.flows) {\n if (flow.expiresAt.getTime() < now) {\n this.flows.delete(state);\n removed++;\n }\n }\n return removed;\n }\n}\n\n// ============================================================\n// Internals\n// ============================================================\n\n/**\n * The MCP SDK reports a 404 PRM lookup with this exact message; treat it\n * as \"PRM is genuinely absent\" and fall back. Anything else is a\n * connection, parse, or 5xx error and is allowed to bubble.\n *\n * Source (verified against `@modelcontextprotocol/sdk@1.29.0`):\n * `dist/esm/client/auth.js` → `discoverOAuthProtectedResourceMetadata`\n * throws `new Error(`Resource server does not implement OAuth 2.0 Protected Resource Metadata.`)`\n * when `response.status === 404` (or no response was returned).\n *\n * If a future MCP SDK reword this message, the test\n * \"falls back to server-derived resource on a 404 PRM\" at\n * `test/lib/oauth-web-flow.test.js` will fail — that test calls the real\n * SDK against a 404 fixture and is the canary for this regression.\n */\nconst PRM_ABSENT_MARKER = 'does not implement OAuth 2.0 Protected Resource Metadata';\n\nasync function tryDiscoverPRM(\n agentUrl: string,\n fetchFn: typeof fetch | undefined\n): Promise<OAuthProtectedResourceMetadata | undefined> {\n try {\n return await discoverOAuthProtectedResourceMetadata(agentUrl, undefined, fetchFn);\n } catch (err) {\n if (err instanceof Error && err.message.includes(PRM_ABSENT_MARKER)) {\n // PRM is optional under RFC 9728 — fall back to local resource\n // derivation. Connection/parse/5xx errors fall through.\n return undefined;\n }\n const message = err instanceof Error ? err.message : String(err);\n throw new ProtectedResourceMetadataError(`PRM discovery failed: ${message}`);\n }\n}\n\nfunction assertPrmResourceMatchesAgentOrigin(agentUrl: string, prmResource: string): void {\n const requested = resourceUrlFromServerUrl(new URL(agentUrl));\n if (!checkResourceAllowed({ requestedResource: requested, configuredResource: prmResource })) {\n throw new ProtectedResourceMetadataError(\n `PRM advertises resource ${prmResource} which does not share an origin/path with agent ${agentUrl}`\n );\n }\n}\n\nfunction resolveAuthorizationServerUrl(agentUrl: string, prm: OAuthProtectedResourceMetadata | undefined): URL {\n const first = prm?.authorization_servers?.[0];\n if (first) {\n return new URL(first);\n }\n return new URL(new URL(agentUrl).origin);\n}\n\nasync function resolveClientInformation(args: {\n agent: AgentConfig;\n agentStorage?: OAuthConfigStorage;\n asUrl: URL;\n asMetadata: AuthorizationServerMetadata;\n clientMetadata: OAuthClientMetadata;\n fetchFn?: typeof fetch;\n allowConfidentialClient: boolean;\n}): Promise<OAuthClientInformation> {\n const { agent, agentStorage, asUrl, asMetadata, clientMetadata, fetchFn, allowConfidentialClient } = args;\n\n if (agent.oauth_client) {\n return toMCPClientInfo(agent.oauth_client);\n }\n\n if (!asMetadata.registration_endpoint) {\n throw new OAuthError(\n 'Agent has no oauth_client and authorization server does not advertise dynamic client registration',\n 'no_client_credentials',\n agent.id\n );\n }\n\n const registered: OAuthClientInformationFull = await registerClient(asUrl.toString(), {\n metadata: asMetadata,\n clientMetadata,\n fetchFn,\n });\n\n if (registered.client_secret && !allowConfidentialClient) {\n throw new ConfidentialClientNotAllowedError(agent.id);\n }\n\n if (agentStorage) {\n // Load fresh and save fresh so two concurrent /start calls for the\n // same agentId do not trample each other's `oauth_client` via a\n // shared in-memory reference.\n const fresh = (await agentStorage.loadAgent(agent.id)) ?? agent;\n fresh.oauth_client = fromMCPClientInfo(registered);\n await agentStorage.saveAgent(fresh);\n }\n\n return registered;\n}\n\nfunction defaultGenerateState(): string {\n return randomBytes(32).toString('base64url');\n}\n\n/**\n * Map an MCP SDK token-exchange failure to {@link TokenExchangeError},\n * redacting bearer/refresh tokens that some authorization servers echo\n * back in error responses for debugging.\n */\nfunction wrapTokenExchangeError(err: unknown): TokenExchangeError {\n // The MCP SDK's `parseErrorResponse` decodes a well-formed OAuth error\n // envelope into an `OAuthError` subclass with `errorCode` (e.g.\n // `InvalidGrantError`). Malformed responses come through as\n // `ServerError` with the raw body in `message`, so the redaction pass\n // covers both cases.\n const oauthErrorCode = (err as { errorCode?: string })?.errorCode;\n const message = err instanceof Error ? err.message : String(err);\n const status = (err as { status?: number })?.status ?? 0;\n const rawBody = (err as { body?: string })?.body ?? message;\n const body = redactTokens(rawBody);\n const display = oauthErrorCode ? `${oauthErrorCode}: ${message}` : message;\n return new TokenExchangeError(`Token exchange failed: ${redactTokens(display)}`, status, body, oauthErrorCode);\n}\n\nconst SENSITIVE_TOKEN_KEYS = ['access_token', 'refresh_token', 'id_token', 'token'];\n\n/**\n * Best-effort redaction of bearer/refresh tokens from an AS error body\n * (which may be JSON, form-encoded, or freeform). Adopters MUST still\n * treat `TokenExchangeError.body` as sensitive — do not reflect it to\n * the browser or write it to access logs unredacted.\n */\nfunction redactTokens(input: string): string {\n let out = input;\n for (const key of SENSITIVE_TOKEN_KEYS) {\n // JSON form: \"key\":\"…\"\n out = out.replace(new RegExp(`(\"${key}\"\\\\s*:\\\\s*\")[^\"]*(\")`, 'gi'), '$1<redacted>$2');\n // form-encoded: key=…\n out = out.replace(new RegExp(`(\\\\b${key}=)[^&\\\\s]+`, 'gi'), '$1<redacted>');\n }\n return out;\n}\n"],"mappings":"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","names":[]}
|
package/dist/lib/brand/index.mjs
CHANGED
|
@@ -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 COMMON_LOGO_SLOTS = [
|
|
8
2
|
"logo_card_light",
|
|
9
3
|
"logo_card_dark",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/brand/index.ts"],"sourcesContent":["import type { RegistryClient, SaveBrandResponse } from '../registry';\nimport type { GetBrandIdentitySuccess } from '../types/core.generated';\n\nexport type BrandJsonRecord = Record<string, unknown>;\ntype ProtocolBrandLogo = NonNullable<GetBrandIdentitySuccess['logos']>[number];\n\nexport type BrandWebsiteAliasRelationship = 'owned';\nexport type BrandWebsiteAliasSource = 'brand_json_property';\n\nexport type BrandLogoOrientation = ProtocolBrandLogo['orientation'];\nexport type BrandLogoBackground = ProtocolBrandLogo['background'];\nexport type BrandLogoVariant = ProtocolBrandLogo['variant'];\n\nexport type BrandAssetExtractionMethod = 'embedded_pdf_image' | 'rendered_page_crop' | 'uploaded_asset' | 'manual';\n\nexport interface BrandAssetCropBox {\n x: number;\n y: number;\n width: number;\n height: number;\n coordinate_space?: 'pixels' | 'normalized_1000';\n}\n\nexport interface BrandAssetCandidate {\n asset_id: string;\n asset_group_id?: string;\n url?: string;\n file?: string;\n source_page?: number;\n extraction_method?: BrandAssetExtractionMethod;\n width?: number;\n height?: number;\n crop_box?: BrandAssetCropBox;\n metadata?: BrandJsonRecord;\n}\n\nexport type BrandAssetMappingTarget = 'logos[]';\nexport type BrandAssetReviewStatus = 'needs_review' | 'approved' | 'rejected';\n\nexport interface BrandLogoProposal extends Omit<ProtocolBrandLogo, 'url'> {\n id: string;\n url?: string;\n slots?: string[];\n [key: string]: unknown;\n}\n\nexport interface BrandAssetMapping {\n asset_id: string;\n target: BrandAssetMappingTarget;\n review_status?: BrandAssetReviewStatus;\n confidence?: number;\n proposed_logo?: BrandLogoProposal;\n evidence?: BrandJsonRecord;\n}\n\nexport interface BrandAssetMappingIssue {\n asset_id?: string;\n message: string;\n}\n\nexport interface BrandAssetMappingValidationResult {\n valid: boolean;\n errors: BrandAssetMappingIssue[];\n warnings: BrandAssetMappingIssue[];\n approvedMappings: BrandAssetMapping[];\n}\n\nexport type ResolveBrandAssetUrl = (\n candidate: BrandAssetCandidate | undefined,\n mapping: BrandAssetMapping\n) => string | undefined;\n\nexport interface ApplyBrandAssetMappingsOptions {\n candidates?: BrandAssetCandidate[];\n mappings: BrandAssetMapping[];\n brandId?: string;\n assetsBaseUrl?: string;\n resolveAssetUrl?: ResolveBrandAssetUrl;\n approvedOnly?: boolean;\n}\n\nexport interface AppliedBrandAssetMapping {\n asset_id: string;\n target: BrandAssetMappingTarget;\n logo_id: string;\n url: string;\n}\n\nexport interface SkippedBrandAssetMapping {\n asset_id?: string;\n target?: BrandAssetMappingTarget;\n reason: string;\n}\n\nexport interface ApplyBrandAssetMappingsResult<TBrandJson extends BrandJsonRecord = BrandJsonRecord> {\n brandJson: TBrandJson;\n appliedMappings: AppliedBrandAssetMapping[];\n skippedMappings: SkippedBrandAssetMapping[];\n warnings: BrandAssetMappingIssue[];\n errors: BrandAssetMappingIssue[];\n}\n\nexport interface LogoSelectionOptions {\n requestedSlot: string;\n brandId?: string;\n background?: BrandLogoBackground;\n preferredVariant?: BrandLogoVariant;\n}\n\nexport interface LogoSlotCoverageOptions {\n brandId?: string;\n}\n\nexport interface LogoSlotCoverage {\n present: string[];\n missing: string[];\n}\n\nexport interface UpdateBrandJsonFromMappingsOptions {\n registryClient: Pick<RegistryClient, 'getBrandJson' | 'saveBrand'>;\n domain: string;\n brandName?: string;\n existingBrandJson?: BrandJsonRecord | null;\n candidates?: BrandAssetCandidate[];\n mappings: BrandAssetMapping[];\n brandId?: string;\n assetsBaseUrl?: string;\n resolveAssetUrl?: ResolveBrandAssetUrl;\n dryRun?: boolean;\n}\n\nexport interface UpdateBrandJsonFromMappingsResult extends ApplyBrandAssetMappingsResult {\n saved: boolean;\n saveResponse?: SaveBrandResponse;\n}\n\nexport interface BrandWebsiteAlias {\n /** Normalized hostname/domain claimed by an owned website property. */\n domain: string;\n /** Where this alias was derived from. */\n source: BrandWebsiteAliasSource;\n /** Manifest path of the source property, e.g. `brands[0].properties[1]`. */\n path: string;\n /** Portfolio-local brand id when the alias came from `brands[]`. */\n brandId?: string;\n /** Human-readable brand name inferred from `name`, `brand_name`, or `names[]`. */\n brandName?: string;\n /** Property display name, when published. */\n propertyName?: string;\n /** Whether the source property was marked primary. */\n primary?: boolean;\n /** Only owned website properties are surfaced as brand aliases. */\n relationship: BrandWebsiteAliasRelationship;\n}\n\nexport interface ExtractBrandWebsiteAliasesOptions {\n /** Restrict extraction to one `brands[]` entry. */\n brandId?: string;\n /**\n * Also inspect non-canonical compatibility fields (`domain`, `url`, and\n * `identifiers[]`). Defaults to false because brand.json property ownership\n * is attached to the canonical `identifier` field.\n */\n includeCompatibilityFields?: boolean;\n}\n\nexport const COMMON_LOGO_SLOTS = [\n 'logo_card_light',\n 'logo_card_dark',\n 'nav_header',\n 'marketplace_listing',\n 'ad_end_card',\n] as const;\n\nexport function validateBrandAssetMappings(input: {\n candidates?: BrandAssetCandidate[];\n mappings: BrandAssetMapping[];\n}): BrandAssetMappingValidationResult {\n const errors: BrandAssetMappingIssue[] = [];\n const warnings: BrandAssetMappingIssue[] = [];\n const candidatesById = indexCandidates(input.candidates ?? [], errors);\n const hasCandidates = (input.candidates?.length ?? 0) > 0;\n const approvedMappings: BrandAssetMapping[] = [];\n\n for (const mapping of input.mappings) {\n if (!mapping.asset_id?.trim()) {\n errors.push({ message: 'mapping.asset_id is required' });\n continue;\n }\n\n if (hasCandidates && !candidatesById.has(mapping.asset_id)) {\n errors.push({ asset_id: mapping.asset_id, message: 'mapping asset_id does not match a candidate asset_id' });\n }\n\n if (mapping.target !== 'logos[]') {\n errors.push({ asset_id: mapping.asset_id, message: `unsupported mapping target: ${String(mapping.target)}` });\n continue;\n }\n\n if (mapping.review_status === 'approved') {\n if (!mapping.proposed_logo) {\n errors.push({ asset_id: mapping.asset_id, message: 'approved logo mapping requires proposed_logo' });\n continue;\n }\n let approvedMappingIsUsable = true;\n if (!mapping.proposed_logo.id?.trim()) {\n errors.push({ asset_id: mapping.asset_id, message: 'approved logo mapping requires proposed_logo.id' });\n approvedMappingIsUsable = false;\n }\n if (approvedMappingIsUsable) approvedMappings.push(mapping);\n } else if (!mapping.review_status) {\n warnings.push({\n asset_id: mapping.asset_id,\n message: 'review_status is missing; mapping will not be applied by default',\n });\n }\n }\n\n return { valid: errors.length === 0, errors, warnings, approvedMappings };\n}\n\nexport function applyBrandAssetMappings<TBrandJson extends BrandJsonRecord>(\n brandJson: TBrandJson,\n options: ApplyBrandAssetMappingsOptions\n): ApplyBrandAssetMappingsResult<TBrandJson> {\n const result = cloneJson(brandJson);\n const warnings: BrandAssetMappingIssue[] = [];\n const errors: BrandAssetMappingIssue[] = [];\n const skippedMappings: SkippedBrandAssetMapping[] = [];\n const appliedMappings: AppliedBrandAssetMapping[] = [];\n const candidatesById = indexCandidates(options.candidates ?? [], errors);\n const targetBrand = resolveWritableBrandRecord(result, options.brandId);\n\n if (!targetBrand.record) {\n return {\n brandJson: result,\n appliedMappings,\n skippedMappings: options.mappings.map(mapping => ({\n asset_id: mapping.asset_id,\n target: mapping.target,\n reason: 'brand record not found',\n })),\n warnings,\n errors: [{ message: targetBrand.reason }],\n };\n }\n\n for (const mapping of options.mappings) {\n if (options.approvedOnly !== false && mapping.review_status !== 'approved') {\n skippedMappings.push({ asset_id: mapping.asset_id, target: mapping.target, reason: 'mapping is not approved' });\n continue;\n }\n\n if (mapping.target !== 'logos[]') {\n skippedMappings.push({\n asset_id: mapping.asset_id,\n target: mapping.target,\n reason: 'unsupported mapping target',\n });\n continue;\n }\n\n if (!mapping.proposed_logo?.id?.trim()) {\n skippedMappings.push({ asset_id: mapping.asset_id, target: mapping.target, reason: 'missing proposed_logo.id' });\n continue;\n }\n\n const candidate = candidatesById.get(mapping.asset_id);\n if (!candidate && (options.candidates?.length ?? 0) > 0) {\n skippedMappings.push({\n asset_id: mapping.asset_id,\n target: mapping.target,\n reason: 'candidate asset_id not found',\n });\n continue;\n }\n\n const url = resolveLogoUrl(candidate, mapping, options);\n if (!url) {\n skippedMappings.push({\n asset_id: mapping.asset_id,\n target: mapping.target,\n reason: 'no durable URL resolved for logo',\n });\n warnings.push({\n asset_id: mapping.asset_id,\n message: 'logo mapping needs proposed_logo.url, candidate.url, or assetsBaseUrl',\n });\n continue;\n }\n\n if (!url.startsWith('https://')) {\n warnings.push({ asset_id: mapping.asset_id, message: 'logo URL is not HTTPS' });\n }\n\n const logo = buildLogoRecord(mapping.proposed_logo, candidate, url);\n upsertLogo(targetBrand.record, logo);\n appliedMappings.push({\n asset_id: mapping.asset_id,\n target: mapping.target,\n logo_id: mapping.proposed_logo.id,\n url,\n });\n }\n\n return { brandJson: result, appliedMappings, skippedMappings, warnings, errors };\n}\n\nexport function selectLogoForSlot(\n brandJsonOrBrand: BrandJsonRecord,\n options: LogoSelectionOptions\n): BrandJsonRecord | null {\n const brand = resolveReadableBrandRecord(brandJsonOrBrand, options.brandId);\n if (!brand.record) return null;\n\n const logos = readLogos(brand.record);\n let best: { logo: BrandJsonRecord; score: number } | null = null;\n\n for (const logo of logos) {\n const slotScore = scoreLogoForSlot(logo, options.requestedSlot);\n if (slotScore == null) continue;\n\n let score = slotScore;\n if (options.background && logo.background === options.background) score += 30;\n if (options.preferredVariant && logo.variant === options.preferredVariant) score += 10;\n\n if (!best || score > best.score) best = { logo, score };\n }\n\n return best?.logo ?? null;\n}\n\nexport function checkLogoSlotCoverage(\n brandJsonOrBrand: BrandJsonRecord,\n requiredSlots: string[],\n options?: LogoSlotCoverageOptions\n): LogoSlotCoverage {\n const present = new Set(\n requiredSlots.filter(slot =>\n selectLogoForSlot(brandJsonOrBrand, { requestedSlot: slot, brandId: options?.brandId })\n )\n );\n\n return {\n present: requiredSlots.filter(slot => present.has(slot)),\n missing: requiredSlots.filter(slot => !present.has(slot)),\n };\n}\n\nexport async function updateBrandJsonFromMappings(\n options: UpdateBrandJsonFromMappingsOptions\n): Promise<UpdateBrandJsonFromMappingsResult> {\n if (!options.domain?.trim()) throw new Error('domain is required');\n\n const existingBrandJson =\n options.existingBrandJson !== undefined\n ? options.existingBrandJson\n : await options.registryClient.getBrandJson(options.domain);\n const baseBrandJson = existingBrandJson ?? { domain: options.domain, name: options.brandName ?? options.domain };\n\n const applied = applyBrandAssetMappings(baseBrandJson, {\n candidates: options.candidates,\n mappings: options.mappings,\n brandId: options.brandId,\n assetsBaseUrl: options.assetsBaseUrl,\n resolveAssetUrl: options.resolveAssetUrl,\n });\n\n if (options.dryRun || applied.errors.length > 0) {\n return { ...applied, saved: false };\n }\n\n const brandName = options.brandName ?? inferBrandName(applied.brandJson, options.brandId) ?? options.domain;\n const saveResponse = await options.registryClient.saveBrand({\n domain: options.domain,\n brand_name: brandName,\n brand_manifest: applied.brandJson,\n });\n\n return { ...applied, saved: true, saveResponse };\n}\n\nexport function extractBrandWebsiteAliases(\n brandJsonOrBrand: BrandJsonRecord,\n options?: ExtractBrandWebsiteAliasesOptions\n): BrandWebsiteAlias[] {\n const aliases: BrandWebsiteAlias[] = [];\n const seen = new Set<string>();\n\n for (const brand of iterateBrandRecords(brandJsonOrBrand, options?.brandId)) {\n const properties = Array.isArray(brand.record.properties) ? brand.record.properties : [];\n for (let propertyIndex = 0; propertyIndex < properties.length; propertyIndex++) {\n const property = properties[propertyIndex];\n if (!isRecord(property)) continue;\n if (!isOwnedWebsiteProperty(property)) continue;\n\n for (const domain of extractWebsitePropertyDomains(property, {\n includeCompatibilityFields: options?.includeCompatibilityFields === true,\n })) {\n if (seen.has(domain)) continue;\n seen.add(domain);\n aliases.push({\n domain,\n source: 'brand_json_property',\n path: propertyPath(brand.path, propertyIndex),\n ...(brand.id ? { brandId: brand.id } : {}),\n ...(brand.name ? { brandName: brand.name } : {}),\n ...(typeof property.name === 'string' && property.name.trim() ? { propertyName: property.name } : {}),\n ...(property.primary === true ? { primary: true } : {}),\n relationship: 'owned',\n });\n }\n }\n }\n\n return aliases;\n}\n\nexport function extractBrandWebsiteAliasDomains(\n brandJsonOrBrand: BrandJsonRecord,\n options?: ExtractBrandWebsiteAliasesOptions\n): string[] {\n return extractBrandWebsiteAliases(brandJsonOrBrand, options).map(alias => alias.domain);\n}\n\nfunction indexCandidates(\n candidates: BrandAssetCandidate[],\n errors: BrandAssetMappingIssue[]\n): Map<string, BrandAssetCandidate> {\n const indexed = new Map<string, BrandAssetCandidate>();\n\n for (const candidate of candidates) {\n if (!candidate.asset_id?.trim()) {\n errors.push({ message: 'candidate.asset_id is required' });\n continue;\n }\n if (indexed.has(candidate.asset_id)) {\n errors.push({ asset_id: candidate.asset_id, message: 'duplicate candidate asset_id' });\n continue;\n }\n indexed.set(candidate.asset_id, candidate);\n }\n\n return indexed;\n}\n\nfunction cloneJson<TBrandJson extends BrandJsonRecord>(value: TBrandJson): TBrandJson {\n return JSON.parse(JSON.stringify(value)) as TBrandJson;\n}\n\nfunction resolveWritableBrandRecord(\n root: BrandJsonRecord,\n brandId?: string\n): { record: BrandJsonRecord | null; reason: string } {\n if (isNonEditableBrandJsonVariant(root)) {\n return { record: null, reason: 'brand.json variant is not editable by logo asset mappings' };\n }\n\n if (Array.isArray(root.brands)) {\n const brands = root.brands.filter(isRecord);\n if (brandId) {\n const brand = brands.find(matchesBrandId(brandId)) ?? null;\n return { record: brand, reason: brand ? '' : `brand not found for brandId: ${brandId}` };\n }\n if (Array.isArray(root.logos)) return { record: root, reason: '' };\n if (brands.length === 1) return { record: brands[0] ?? null, reason: '' };\n return { record: null, reason: 'brandId is required for multi-brand brand.json documents' };\n }\n\n if (Array.isArray(root.logos)) return { record: root, reason: '' };\n\n if (!isTopLevelBrandIdentity(root)) {\n return { record: null, reason: 'brand record not found' };\n }\n root.logos = [];\n return { record: root, reason: '' };\n}\n\nfunction resolveLogoUrl(\n candidate: BrandAssetCandidate | undefined,\n mapping: BrandAssetMapping,\n options: ApplyBrandAssetMappingsOptions\n): string | undefined {\n const resolved = options.resolveAssetUrl?.(candidate, mapping);\n if (resolved) return resolved;\n if (mapping.proposed_logo?.url) return mapping.proposed_logo.url;\n if (candidate?.url) return candidate.url;\n\n const baseUrl = removeTrailingSlashes(options.assetsBaseUrl);\n if (!baseUrl || !candidate) return undefined;\n\n const path = candidate.file ?? candidate.asset_id;\n return `${baseUrl}/${path\n .split('/')\n .filter(Boolean)\n .map(segment => encodeURIComponent(segment))\n .join('/')}`;\n}\n\nfunction removeTrailingSlashes(value: string | undefined): string | undefined {\n if (!value) return value;\n\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 47) {\n end -= 1;\n }\n return value.slice(0, end);\n}\n\nfunction buildLogoRecord(\n proposal: BrandLogoProposal,\n candidate: BrandAssetCandidate | undefined,\n url: string\n): BrandJsonRecord {\n const logo: BrandJsonRecord = { ...proposal, url };\n if (logo.width === undefined && candidate?.width !== undefined) logo.width = candidate.width;\n if (logo.height === undefined && candidate?.height !== undefined) logo.height = candidate.height;\n return logo;\n}\n\nfunction upsertLogo(brand: BrandJsonRecord, logo: BrandJsonRecord): void {\n const currentLogos = Array.isArray(brand.logos) ? brand.logos : [];\n const logos = currentLogos.filter(isRecord);\n const logoId = typeof logo.id === 'string' ? logo.id : undefined;\n const existingIndex = logoId ? logos.findIndex(existing => existing.id === logoId) : -1;\n\n if (existingIndex >= 0) {\n logos[existingIndex] = { ...logos[existingIndex], ...logo };\n } else {\n logos.push(logo);\n }\n\n brand.logos = logos;\n}\n\nfunction readLogos(brandJsonOrBrand: BrandJsonRecord): BrandJsonRecord[] {\n if (Array.isArray(brandJsonOrBrand.logos)) return brandJsonOrBrand.logos.filter(isRecord);\n return [];\n}\n\nfunction iterateBrandRecords(\n root: BrandJsonRecord,\n brandId?: string\n): Array<{ record: BrandJsonRecord; path: string; id?: string; name?: string }> {\n if (!Array.isArray(root.brands)) {\n return [{ record: root, path: '', id: readBrandId(root), name: inferBrandName(root) }];\n }\n\n const records: Array<{ record: BrandJsonRecord; path: string; id?: string; name?: string }> = [];\n for (let brandIndex = 0; brandIndex < root.brands.length; brandIndex++) {\n const brand = root.brands[brandIndex];\n if (!isRecord(brand)) continue;\n if (brandId && !matchesBrandId(brandId)(brand)) continue;\n records.push({ record: brand, path: `brands[${brandIndex}]`, id: readBrandId(brand), name: inferBrandName(brand) });\n }\n return records;\n}\n\nfunction propertyPath(brandPath: string, propertyIndex: number): string {\n return brandPath ? `${brandPath}.properties[${propertyIndex}]` : `properties[${propertyIndex}]`;\n}\n\nfunction readBrandId(brand: BrandJsonRecord): string | undefined {\n if (typeof brand.id === 'string' && brand.id.trim()) return brand.id;\n if (typeof brand.brand_id === 'string' && brand.brand_id.trim()) return brand.brand_id;\n return undefined;\n}\n\nfunction isOwnedWebsiteProperty(property: BrandJsonRecord): boolean {\n const propertyType = property.type ?? property.property_type;\n if (propertyType !== 'website') return false;\n\n const relationship = property.relationship;\n if (relationship !== undefined && relationship !== 'owned') return false;\n\n const delegationType = property.delegation_type;\n if (delegationType === 'direct' || delegationType === 'delegated' || delegationType === 'ad_network') return false;\n\n return true;\n}\n\nfunction extractWebsitePropertyDomains(\n property: BrandJsonRecord,\n options: { includeCompatibilityFields: boolean }\n): string[] {\n const domains: string[] = [];\n const seen = new Set<string>();\n const add = (value: unknown): void => {\n const domain = normalizeWebsiteDomain(value);\n if (!domain || seen.has(domain)) return;\n seen.add(domain);\n domains.push(domain);\n };\n\n add(property.identifier);\n\n if (!options.includeCompatibilityFields) return domains;\n\n add(property.domain);\n add(property.url);\n\n if (Array.isArray(property.identifiers)) {\n for (const identifier of property.identifiers) {\n if (!isRecord(identifier)) continue;\n if (identifier.type !== 'domain' && identifier.type !== 'subdomain') continue;\n add(identifier.value);\n add(identifier.identifier);\n add(identifier.domain);\n add(identifier.url);\n }\n }\n\n return domains;\n}\n\nfunction normalizeWebsiteDomain(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n let candidate = trimmed;\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(candidate) && !candidate.startsWith('//')) {\n candidate = `https://${candidate}`;\n }\n\n let parsed: URL;\n try {\n parsed = new URL(candidate);\n } catch {\n return null;\n }\n\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') return null;\n if (parsed.username || parsed.password) return null;\n\n const hostname = parsed.hostname.toLowerCase();\n return isDomainLikeHost(hostname) ? hostname : null;\n}\n\nfunction isDomainLikeHost(hostname: string): boolean {\n if (hostname.length === 0 || hostname.length > 253 || !hostname.includes('.')) return false;\n if (hostname.startsWith('.') || hostname.endsWith('.')) return false;\n\n const labels = hostname.split('.');\n return labels.every(label => {\n return label.length > 0 && label.length <= 63 && /^([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])$/.test(label);\n });\n}\n\nfunction scoreLogoForSlot(logo: BrandJsonRecord, requestedSlot: string): number | null {\n if (arrayOfStrings(logo.slots).includes(requestedSlot)) return 100;\n\n switch (requestedSlot) {\n case 'logo_card_light':\n return logo.background === 'light-bg' || logo.background === 'transparent-bg' ? 50 : null;\n case 'logo_card_dark':\n return logo.background === 'dark-bg' || logo.background === 'transparent-bg' ? 50 : null;\n case 'nav_header':\n return logo.orientation === 'horizontal' || logo.variant === 'wordmark' || logo.variant === 'full-lockup'\n ? 40\n : null;\n case 'marketplace_listing':\n return logo.variant === 'primary' || logo.variant === 'full-lockup' || logo.variant === 'icon' ? 30 : null;\n case 'ad_end_card':\n return logo.background === 'dark-bg' || logo.background === 'light-bg' || logo.background === 'transparent-bg'\n ? 20\n : null;\n default:\n return null;\n }\n}\n\nfunction arrayOfStrings(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [];\n}\n\nfunction inferBrandName(brandJson: BrandJsonRecord, brandId?: string): string | undefined {\n const brandRecord = findReadableBrandRecord(brandJson, brandId);\n if (typeof brandRecord?.name === 'string' && brandRecord.name.trim()) return brandRecord.name;\n if (typeof brandRecord?.brand_name === 'string' && brandRecord.brand_name.trim()) return brandRecord.brand_name;\n const localizedBrandName = readLocalizedName(brandRecord?.names);\n if (localizedBrandName) return localizedBrandName;\n if (typeof brandJson.name === 'string' && brandJson.name.trim()) return brandJson.name;\n if (typeof brandJson.brand_name === 'string' && brandJson.brand_name.trim()) return brandJson.brand_name;\n const localizedRootName = readLocalizedName(brandJson.names);\n if (localizedRootName) return localizedRootName;\n return undefined;\n}\n\nfunction findReadableBrandRecord(root: BrandJsonRecord, brandId?: string): BrandJsonRecord | null {\n return resolveReadableBrandRecord(root, brandId).record;\n}\n\nfunction resolveReadableBrandRecord(\n root: BrandJsonRecord,\n brandId?: string\n): { record: BrandJsonRecord | null; reason: string } {\n if (Array.isArray(root.brands)) {\n const brands = root.brands.filter(isRecord);\n if (brandId) {\n const brand = brands.find(matchesBrandId(brandId)) ?? null;\n return { record: brand, reason: brand ? '' : `brand not found for brandId: ${brandId}` };\n }\n if (Array.isArray(root.logos)) return { record: root, reason: '' };\n if (brands.length === 1) return { record: brands[0] ?? null, reason: '' };\n return { record: null, reason: 'brandId is required for multi-brand brand.json documents' };\n }\n\n return { record: root, reason: '' };\n}\n\nfunction matchesBrandId(brandId: string): (brand: BrandJsonRecord) => boolean {\n return brand => brand.id === brandId || brand.brand_id === brandId || brand.domain === brandId;\n}\n\nfunction isNonEditableBrandJsonVariant(root: BrandJsonRecord): boolean {\n if (typeof root.authoritative_location === 'string') return true;\n if (typeof root.house === 'string') return true;\n\n const hasIdentityFields =\n Array.isArray(root.brands) ||\n Array.isArray(root.logos) ||\n typeof root.domain === 'string' ||\n typeof root.name === 'string' ||\n typeof root.brand_name === 'string' ||\n Array.isArray(root.names);\n\n return Array.isArray(root.agents) && !hasIdentityFields;\n}\n\nfunction isTopLevelBrandIdentity(root: BrandJsonRecord): boolean {\n return (\n typeof root.domain === 'string' ||\n typeof root.name === 'string' ||\n typeof root.brand_name === 'string' ||\n Array.isArray(root.names)\n );\n}\n\nfunction isRecord(value: unknown): value is BrandJsonRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readLocalizedName(value: unknown): string | undefined {\n if (!Array.isArray(value)) return undefined;\n\n for (const entry of value) {\n if (!isRecord(entry)) continue;\n if (typeof entry.en === 'string' && entry.en.trim()) return entry.en;\n for (const name of Object.values(entry)) {\n if (typeof name === 'string' && name.trim()) return name;\n }\n }\n\n return undefined;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/brand/index.ts"],"sourcesContent":["import type { RegistryClient, SaveBrandResponse } from '../registry';\nimport type { GetBrandIdentitySuccess } from '../types/core.generated';\n\nexport type BrandJsonRecord = Record<string, unknown>;\ntype ProtocolBrandLogo = NonNullable<GetBrandIdentitySuccess['logos']>[number];\n\nexport type BrandWebsiteAliasRelationship = 'owned';\nexport type BrandWebsiteAliasSource = 'brand_json_property';\n\nexport type BrandLogoOrientation = ProtocolBrandLogo['orientation'];\nexport type BrandLogoBackground = ProtocolBrandLogo['background'];\nexport type BrandLogoVariant = ProtocolBrandLogo['variant'];\n\nexport type BrandAssetExtractionMethod = 'embedded_pdf_image' | 'rendered_page_crop' | 'uploaded_asset' | 'manual';\n\nexport interface BrandAssetCropBox {\n x: number;\n y: number;\n width: number;\n height: number;\n coordinate_space?: 'pixels' | 'normalized_1000';\n}\n\nexport interface BrandAssetCandidate {\n asset_id: string;\n asset_group_id?: string;\n url?: string;\n file?: string;\n source_page?: number;\n extraction_method?: BrandAssetExtractionMethod;\n width?: number;\n height?: number;\n crop_box?: BrandAssetCropBox;\n metadata?: BrandJsonRecord;\n}\n\nexport type BrandAssetMappingTarget = 'logos[]';\nexport type BrandAssetReviewStatus = 'needs_review' | 'approved' | 'rejected';\n\nexport interface BrandLogoProposal extends Omit<ProtocolBrandLogo, 'url'> {\n id: string;\n url?: string;\n slots?: string[];\n [key: string]: unknown;\n}\n\nexport interface BrandAssetMapping {\n asset_id: string;\n target: BrandAssetMappingTarget;\n review_status?: BrandAssetReviewStatus;\n confidence?: number;\n proposed_logo?: BrandLogoProposal;\n evidence?: BrandJsonRecord;\n}\n\nexport interface BrandAssetMappingIssue {\n asset_id?: string;\n message: string;\n}\n\nexport interface BrandAssetMappingValidationResult {\n valid: boolean;\n errors: BrandAssetMappingIssue[];\n warnings: BrandAssetMappingIssue[];\n approvedMappings: BrandAssetMapping[];\n}\n\nexport type ResolveBrandAssetUrl = (\n candidate: BrandAssetCandidate | undefined,\n mapping: BrandAssetMapping\n) => string | undefined;\n\nexport interface ApplyBrandAssetMappingsOptions {\n candidates?: BrandAssetCandidate[];\n mappings: BrandAssetMapping[];\n brandId?: string;\n assetsBaseUrl?: string;\n resolveAssetUrl?: ResolveBrandAssetUrl;\n approvedOnly?: boolean;\n}\n\nexport interface AppliedBrandAssetMapping {\n asset_id: string;\n target: BrandAssetMappingTarget;\n logo_id: string;\n url: string;\n}\n\nexport interface SkippedBrandAssetMapping {\n asset_id?: string;\n target?: BrandAssetMappingTarget;\n reason: string;\n}\n\nexport interface ApplyBrandAssetMappingsResult<TBrandJson extends BrandJsonRecord = BrandJsonRecord> {\n brandJson: TBrandJson;\n appliedMappings: AppliedBrandAssetMapping[];\n skippedMappings: SkippedBrandAssetMapping[];\n warnings: BrandAssetMappingIssue[];\n errors: BrandAssetMappingIssue[];\n}\n\nexport interface LogoSelectionOptions {\n requestedSlot: string;\n brandId?: string;\n background?: BrandLogoBackground;\n preferredVariant?: BrandLogoVariant;\n}\n\nexport interface LogoSlotCoverageOptions {\n brandId?: string;\n}\n\nexport interface LogoSlotCoverage {\n present: string[];\n missing: string[];\n}\n\nexport interface UpdateBrandJsonFromMappingsOptions {\n registryClient: Pick<RegistryClient, 'getBrandJson' | 'saveBrand'>;\n domain: string;\n brandName?: string;\n existingBrandJson?: BrandJsonRecord | null;\n candidates?: BrandAssetCandidate[];\n mappings: BrandAssetMapping[];\n brandId?: string;\n assetsBaseUrl?: string;\n resolveAssetUrl?: ResolveBrandAssetUrl;\n dryRun?: boolean;\n}\n\nexport interface UpdateBrandJsonFromMappingsResult extends ApplyBrandAssetMappingsResult {\n saved: boolean;\n saveResponse?: SaveBrandResponse;\n}\n\nexport interface BrandWebsiteAlias {\n /** Normalized hostname/domain claimed by an owned website property. */\n domain: string;\n /** Where this alias was derived from. */\n source: BrandWebsiteAliasSource;\n /** Manifest path of the source property, e.g. `brands[0].properties[1]`. */\n path: string;\n /** Portfolio-local brand id when the alias came from `brands[]`. */\n brandId?: string;\n /** Human-readable brand name inferred from `name`, `brand_name`, or `names[]`. */\n brandName?: string;\n /** Property display name, when published. */\n propertyName?: string;\n /** Whether the source property was marked primary. */\n primary?: boolean;\n /** Only owned website properties are surfaced as brand aliases. */\n relationship: BrandWebsiteAliasRelationship;\n}\n\nexport interface ExtractBrandWebsiteAliasesOptions {\n /** Restrict extraction to one `brands[]` entry. */\n brandId?: string;\n /**\n * Also inspect non-canonical compatibility fields (`domain`, `url`, and\n * `identifiers[]`). Defaults to false because brand.json property ownership\n * is attached to the canonical `identifier` field.\n */\n includeCompatibilityFields?: boolean;\n}\n\nexport const COMMON_LOGO_SLOTS = [\n 'logo_card_light',\n 'logo_card_dark',\n 'nav_header',\n 'marketplace_listing',\n 'ad_end_card',\n] as const;\n\nexport function validateBrandAssetMappings(input: {\n candidates?: BrandAssetCandidate[];\n mappings: BrandAssetMapping[];\n}): BrandAssetMappingValidationResult {\n const errors: BrandAssetMappingIssue[] = [];\n const warnings: BrandAssetMappingIssue[] = [];\n const candidatesById = indexCandidates(input.candidates ?? [], errors);\n const hasCandidates = (input.candidates?.length ?? 0) > 0;\n const approvedMappings: BrandAssetMapping[] = [];\n\n for (const mapping of input.mappings) {\n if (!mapping.asset_id?.trim()) {\n errors.push({ message: 'mapping.asset_id is required' });\n continue;\n }\n\n if (hasCandidates && !candidatesById.has(mapping.asset_id)) {\n errors.push({ asset_id: mapping.asset_id, message: 'mapping asset_id does not match a candidate asset_id' });\n }\n\n if (mapping.target !== 'logos[]') {\n errors.push({ asset_id: mapping.asset_id, message: `unsupported mapping target: ${String(mapping.target)}` });\n continue;\n }\n\n if (mapping.review_status === 'approved') {\n if (!mapping.proposed_logo) {\n errors.push({ asset_id: mapping.asset_id, message: 'approved logo mapping requires proposed_logo' });\n continue;\n }\n let approvedMappingIsUsable = true;\n if (!mapping.proposed_logo.id?.trim()) {\n errors.push({ asset_id: mapping.asset_id, message: 'approved logo mapping requires proposed_logo.id' });\n approvedMappingIsUsable = false;\n }\n if (approvedMappingIsUsable) approvedMappings.push(mapping);\n } else if (!mapping.review_status) {\n warnings.push({\n asset_id: mapping.asset_id,\n message: 'review_status is missing; mapping will not be applied by default',\n });\n }\n }\n\n return { valid: errors.length === 0, errors, warnings, approvedMappings };\n}\n\nexport function applyBrandAssetMappings<TBrandJson extends BrandJsonRecord>(\n brandJson: TBrandJson,\n options: ApplyBrandAssetMappingsOptions\n): ApplyBrandAssetMappingsResult<TBrandJson> {\n const result = cloneJson(brandJson);\n const warnings: BrandAssetMappingIssue[] = [];\n const errors: BrandAssetMappingIssue[] = [];\n const skippedMappings: SkippedBrandAssetMapping[] = [];\n const appliedMappings: AppliedBrandAssetMapping[] = [];\n const candidatesById = indexCandidates(options.candidates ?? [], errors);\n const targetBrand = resolveWritableBrandRecord(result, options.brandId);\n\n if (!targetBrand.record) {\n return {\n brandJson: result,\n appliedMappings,\n skippedMappings: options.mappings.map(mapping => ({\n asset_id: mapping.asset_id,\n target: mapping.target,\n reason: 'brand record not found',\n })),\n warnings,\n errors: [{ message: targetBrand.reason }],\n };\n }\n\n for (const mapping of options.mappings) {\n if (options.approvedOnly !== false && mapping.review_status !== 'approved') {\n skippedMappings.push({ asset_id: mapping.asset_id, target: mapping.target, reason: 'mapping is not approved' });\n continue;\n }\n\n if (mapping.target !== 'logos[]') {\n skippedMappings.push({\n asset_id: mapping.asset_id,\n target: mapping.target,\n reason: 'unsupported mapping target',\n });\n continue;\n }\n\n if (!mapping.proposed_logo?.id?.trim()) {\n skippedMappings.push({ asset_id: mapping.asset_id, target: mapping.target, reason: 'missing proposed_logo.id' });\n continue;\n }\n\n const candidate = candidatesById.get(mapping.asset_id);\n if (!candidate && (options.candidates?.length ?? 0) > 0) {\n skippedMappings.push({\n asset_id: mapping.asset_id,\n target: mapping.target,\n reason: 'candidate asset_id not found',\n });\n continue;\n }\n\n const url = resolveLogoUrl(candidate, mapping, options);\n if (!url) {\n skippedMappings.push({\n asset_id: mapping.asset_id,\n target: mapping.target,\n reason: 'no durable URL resolved for logo',\n });\n warnings.push({\n asset_id: mapping.asset_id,\n message: 'logo mapping needs proposed_logo.url, candidate.url, or assetsBaseUrl',\n });\n continue;\n }\n\n if (!url.startsWith('https://')) {\n warnings.push({ asset_id: mapping.asset_id, message: 'logo URL is not HTTPS' });\n }\n\n const logo = buildLogoRecord(mapping.proposed_logo, candidate, url);\n upsertLogo(targetBrand.record, logo);\n appliedMappings.push({\n asset_id: mapping.asset_id,\n target: mapping.target,\n logo_id: mapping.proposed_logo.id,\n url,\n });\n }\n\n return { brandJson: result, appliedMappings, skippedMappings, warnings, errors };\n}\n\nexport function selectLogoForSlot(\n brandJsonOrBrand: BrandJsonRecord,\n options: LogoSelectionOptions\n): BrandJsonRecord | null {\n const brand = resolveReadableBrandRecord(brandJsonOrBrand, options.brandId);\n if (!brand.record) return null;\n\n const logos = readLogos(brand.record);\n let best: { logo: BrandJsonRecord; score: number } | null = null;\n\n for (const logo of logos) {\n const slotScore = scoreLogoForSlot(logo, options.requestedSlot);\n if (slotScore == null) continue;\n\n let score = slotScore;\n if (options.background && logo.background === options.background) score += 30;\n if (options.preferredVariant && logo.variant === options.preferredVariant) score += 10;\n\n if (!best || score > best.score) best = { logo, score };\n }\n\n return best?.logo ?? null;\n}\n\nexport function checkLogoSlotCoverage(\n brandJsonOrBrand: BrandJsonRecord,\n requiredSlots: string[],\n options?: LogoSlotCoverageOptions\n): LogoSlotCoverage {\n const present = new Set(\n requiredSlots.filter(slot =>\n selectLogoForSlot(brandJsonOrBrand, { requestedSlot: slot, brandId: options?.brandId })\n )\n );\n\n return {\n present: requiredSlots.filter(slot => present.has(slot)),\n missing: requiredSlots.filter(slot => !present.has(slot)),\n };\n}\n\nexport async function updateBrandJsonFromMappings(\n options: UpdateBrandJsonFromMappingsOptions\n): Promise<UpdateBrandJsonFromMappingsResult> {\n if (!options.domain?.trim()) throw new Error('domain is required');\n\n const existingBrandJson =\n options.existingBrandJson !== undefined\n ? options.existingBrandJson\n : await options.registryClient.getBrandJson(options.domain);\n const baseBrandJson = existingBrandJson ?? { domain: options.domain, name: options.brandName ?? options.domain };\n\n const applied = applyBrandAssetMappings(baseBrandJson, {\n candidates: options.candidates,\n mappings: options.mappings,\n brandId: options.brandId,\n assetsBaseUrl: options.assetsBaseUrl,\n resolveAssetUrl: options.resolveAssetUrl,\n });\n\n if (options.dryRun || applied.errors.length > 0) {\n return { ...applied, saved: false };\n }\n\n const brandName = options.brandName ?? inferBrandName(applied.brandJson, options.brandId) ?? options.domain;\n const saveResponse = await options.registryClient.saveBrand({\n domain: options.domain,\n brand_name: brandName,\n brand_manifest: applied.brandJson,\n });\n\n return { ...applied, saved: true, saveResponse };\n}\n\nexport function extractBrandWebsiteAliases(\n brandJsonOrBrand: BrandJsonRecord,\n options?: ExtractBrandWebsiteAliasesOptions\n): BrandWebsiteAlias[] {\n const aliases: BrandWebsiteAlias[] = [];\n const seen = new Set<string>();\n\n for (const brand of iterateBrandRecords(brandJsonOrBrand, options?.brandId)) {\n const properties = Array.isArray(brand.record.properties) ? brand.record.properties : [];\n for (let propertyIndex = 0; propertyIndex < properties.length; propertyIndex++) {\n const property = properties[propertyIndex];\n if (!isRecord(property)) continue;\n if (!isOwnedWebsiteProperty(property)) continue;\n\n for (const domain of extractWebsitePropertyDomains(property, {\n includeCompatibilityFields: options?.includeCompatibilityFields === true,\n })) {\n if (seen.has(domain)) continue;\n seen.add(domain);\n aliases.push({\n domain,\n source: 'brand_json_property',\n path: propertyPath(brand.path, propertyIndex),\n ...(brand.id ? { brandId: brand.id } : {}),\n ...(brand.name ? { brandName: brand.name } : {}),\n ...(typeof property.name === 'string' && property.name.trim() ? { propertyName: property.name } : {}),\n ...(property.primary === true ? { primary: true } : {}),\n relationship: 'owned',\n });\n }\n }\n }\n\n return aliases;\n}\n\nexport function extractBrandWebsiteAliasDomains(\n brandJsonOrBrand: BrandJsonRecord,\n options?: ExtractBrandWebsiteAliasesOptions\n): string[] {\n return extractBrandWebsiteAliases(brandJsonOrBrand, options).map(alias => alias.domain);\n}\n\nfunction indexCandidates(\n candidates: BrandAssetCandidate[],\n errors: BrandAssetMappingIssue[]\n): Map<string, BrandAssetCandidate> {\n const indexed = new Map<string, BrandAssetCandidate>();\n\n for (const candidate of candidates) {\n if (!candidate.asset_id?.trim()) {\n errors.push({ message: 'candidate.asset_id is required' });\n continue;\n }\n if (indexed.has(candidate.asset_id)) {\n errors.push({ asset_id: candidate.asset_id, message: 'duplicate candidate asset_id' });\n continue;\n }\n indexed.set(candidate.asset_id, candidate);\n }\n\n return indexed;\n}\n\nfunction cloneJson<TBrandJson extends BrandJsonRecord>(value: TBrandJson): TBrandJson {\n return JSON.parse(JSON.stringify(value)) as TBrandJson;\n}\n\nfunction resolveWritableBrandRecord(\n root: BrandJsonRecord,\n brandId?: string\n): { record: BrandJsonRecord | null; reason: string } {\n if (isNonEditableBrandJsonVariant(root)) {\n return { record: null, reason: 'brand.json variant is not editable by logo asset mappings' };\n }\n\n if (Array.isArray(root.brands)) {\n const brands = root.brands.filter(isRecord);\n if (brandId) {\n const brand = brands.find(matchesBrandId(brandId)) ?? null;\n return { record: brand, reason: brand ? '' : `brand not found for brandId: ${brandId}` };\n }\n if (Array.isArray(root.logos)) return { record: root, reason: '' };\n if (brands.length === 1) return { record: brands[0] ?? null, reason: '' };\n return { record: null, reason: 'brandId is required for multi-brand brand.json documents' };\n }\n\n if (Array.isArray(root.logos)) return { record: root, reason: '' };\n\n if (!isTopLevelBrandIdentity(root)) {\n return { record: null, reason: 'brand record not found' };\n }\n root.logos = [];\n return { record: root, reason: '' };\n}\n\nfunction resolveLogoUrl(\n candidate: BrandAssetCandidate | undefined,\n mapping: BrandAssetMapping,\n options: ApplyBrandAssetMappingsOptions\n): string | undefined {\n const resolved = options.resolveAssetUrl?.(candidate, mapping);\n if (resolved) return resolved;\n if (mapping.proposed_logo?.url) return mapping.proposed_logo.url;\n if (candidate?.url) return candidate.url;\n\n const baseUrl = removeTrailingSlashes(options.assetsBaseUrl);\n if (!baseUrl || !candidate) return undefined;\n\n const path = candidate.file ?? candidate.asset_id;\n return `${baseUrl}/${path\n .split('/')\n .filter(Boolean)\n .map(segment => encodeURIComponent(segment))\n .join('/')}`;\n}\n\nfunction removeTrailingSlashes(value: string | undefined): string | undefined {\n if (!value) return value;\n\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 47) {\n end -= 1;\n }\n return value.slice(0, end);\n}\n\nfunction buildLogoRecord(\n proposal: BrandLogoProposal,\n candidate: BrandAssetCandidate | undefined,\n url: string\n): BrandJsonRecord {\n const logo: BrandJsonRecord = { ...proposal, url };\n if (logo.width === undefined && candidate?.width !== undefined) logo.width = candidate.width;\n if (logo.height === undefined && candidate?.height !== undefined) logo.height = candidate.height;\n return logo;\n}\n\nfunction upsertLogo(brand: BrandJsonRecord, logo: BrandJsonRecord): void {\n const currentLogos = Array.isArray(brand.logos) ? brand.logos : [];\n const logos = currentLogos.filter(isRecord);\n const logoId = typeof logo.id === 'string' ? logo.id : undefined;\n const existingIndex = logoId ? logos.findIndex(existing => existing.id === logoId) : -1;\n\n if (existingIndex >= 0) {\n logos[existingIndex] = { ...logos[existingIndex], ...logo };\n } else {\n logos.push(logo);\n }\n\n brand.logos = logos;\n}\n\nfunction readLogos(brandJsonOrBrand: BrandJsonRecord): BrandJsonRecord[] {\n if (Array.isArray(brandJsonOrBrand.logos)) return brandJsonOrBrand.logos.filter(isRecord);\n return [];\n}\n\nfunction iterateBrandRecords(\n root: BrandJsonRecord,\n brandId?: string\n): Array<{ record: BrandJsonRecord; path: string; id?: string; name?: string }> {\n if (!Array.isArray(root.brands)) {\n return [{ record: root, path: '', id: readBrandId(root), name: inferBrandName(root) }];\n }\n\n const records: Array<{ record: BrandJsonRecord; path: string; id?: string; name?: string }> = [];\n for (let brandIndex = 0; brandIndex < root.brands.length; brandIndex++) {\n const brand = root.brands[brandIndex];\n if (!isRecord(brand)) continue;\n if (brandId && !matchesBrandId(brandId)(brand)) continue;\n records.push({ record: brand, path: `brands[${brandIndex}]`, id: readBrandId(brand), name: inferBrandName(brand) });\n }\n return records;\n}\n\nfunction propertyPath(brandPath: string, propertyIndex: number): string {\n return brandPath ? `${brandPath}.properties[${propertyIndex}]` : `properties[${propertyIndex}]`;\n}\n\nfunction readBrandId(brand: BrandJsonRecord): string | undefined {\n if (typeof brand.id === 'string' && brand.id.trim()) return brand.id;\n if (typeof brand.brand_id === 'string' && brand.brand_id.trim()) return brand.brand_id;\n return undefined;\n}\n\nfunction isOwnedWebsiteProperty(property: BrandJsonRecord): boolean {\n const propertyType = property.type ?? property.property_type;\n if (propertyType !== 'website') return false;\n\n const relationship = property.relationship;\n if (relationship !== undefined && relationship !== 'owned') return false;\n\n const delegationType = property.delegation_type;\n if (delegationType === 'direct' || delegationType === 'delegated' || delegationType === 'ad_network') return false;\n\n return true;\n}\n\nfunction extractWebsitePropertyDomains(\n property: BrandJsonRecord,\n options: { includeCompatibilityFields: boolean }\n): string[] {\n const domains: string[] = [];\n const seen = new Set<string>();\n const add = (value: unknown): void => {\n const domain = normalizeWebsiteDomain(value);\n if (!domain || seen.has(domain)) return;\n seen.add(domain);\n domains.push(domain);\n };\n\n add(property.identifier);\n\n if (!options.includeCompatibilityFields) return domains;\n\n add(property.domain);\n add(property.url);\n\n if (Array.isArray(property.identifiers)) {\n for (const identifier of property.identifiers) {\n if (!isRecord(identifier)) continue;\n if (identifier.type !== 'domain' && identifier.type !== 'subdomain') continue;\n add(identifier.value);\n add(identifier.identifier);\n add(identifier.domain);\n add(identifier.url);\n }\n }\n\n return domains;\n}\n\nfunction normalizeWebsiteDomain(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n let candidate = trimmed;\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(candidate) && !candidate.startsWith('//')) {\n candidate = `https://${candidate}`;\n }\n\n let parsed: URL;\n try {\n parsed = new URL(candidate);\n } catch {\n return null;\n }\n\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') return null;\n if (parsed.username || parsed.password) return null;\n\n const hostname = parsed.hostname.toLowerCase();\n return isDomainLikeHost(hostname) ? hostname : null;\n}\n\nfunction isDomainLikeHost(hostname: string): boolean {\n if (hostname.length === 0 || hostname.length > 253 || !hostname.includes('.')) return false;\n if (hostname.startsWith('.') || hostname.endsWith('.')) return false;\n\n const labels = hostname.split('.');\n return labels.every(label => {\n return label.length > 0 && label.length <= 63 && /^([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])$/.test(label);\n });\n}\n\nfunction scoreLogoForSlot(logo: BrandJsonRecord, requestedSlot: string): number | null {\n if (arrayOfStrings(logo.slots).includes(requestedSlot)) return 100;\n\n switch (requestedSlot) {\n case 'logo_card_light':\n return logo.background === 'light-bg' || logo.background === 'transparent-bg' ? 50 : null;\n case 'logo_card_dark':\n return logo.background === 'dark-bg' || logo.background === 'transparent-bg' ? 50 : null;\n case 'nav_header':\n return logo.orientation === 'horizontal' || logo.variant === 'wordmark' || logo.variant === 'full-lockup'\n ? 40\n : null;\n case 'marketplace_listing':\n return logo.variant === 'primary' || logo.variant === 'full-lockup' || logo.variant === 'icon' ? 30 : null;\n case 'ad_end_card':\n return logo.background === 'dark-bg' || logo.background === 'light-bg' || logo.background === 'transparent-bg'\n ? 20\n : null;\n default:\n return null;\n }\n}\n\nfunction arrayOfStrings(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [];\n}\n\nfunction inferBrandName(brandJson: BrandJsonRecord, brandId?: string): string | undefined {\n const brandRecord = findReadableBrandRecord(brandJson, brandId);\n if (typeof brandRecord?.name === 'string' && brandRecord.name.trim()) return brandRecord.name;\n if (typeof brandRecord?.brand_name === 'string' && brandRecord.brand_name.trim()) return brandRecord.brand_name;\n const localizedBrandName = readLocalizedName(brandRecord?.names);\n if (localizedBrandName) return localizedBrandName;\n if (typeof brandJson.name === 'string' && brandJson.name.trim()) return brandJson.name;\n if (typeof brandJson.brand_name === 'string' && brandJson.brand_name.trim()) return brandJson.brand_name;\n const localizedRootName = readLocalizedName(brandJson.names);\n if (localizedRootName) return localizedRootName;\n return undefined;\n}\n\nfunction findReadableBrandRecord(root: BrandJsonRecord, brandId?: string): BrandJsonRecord | null {\n return resolveReadableBrandRecord(root, brandId).record;\n}\n\nfunction resolveReadableBrandRecord(\n root: BrandJsonRecord,\n brandId?: string\n): { record: BrandJsonRecord | null; reason: string } {\n if (Array.isArray(root.brands)) {\n const brands = root.brands.filter(isRecord);\n if (brandId) {\n const brand = brands.find(matchesBrandId(brandId)) ?? null;\n return { record: brand, reason: brand ? '' : `brand not found for brandId: ${brandId}` };\n }\n if (Array.isArray(root.logos)) return { record: root, reason: '' };\n if (brands.length === 1) return { record: brands[0] ?? null, reason: '' };\n return { record: null, reason: 'brandId is required for multi-brand brand.json documents' };\n }\n\n return { record: root, reason: '' };\n}\n\nfunction matchesBrandId(brandId: string): (brand: BrandJsonRecord) => boolean {\n return brand => brand.id === brandId || brand.brand_id === brandId || brand.domain === brandId;\n}\n\nfunction isNonEditableBrandJsonVariant(root: BrandJsonRecord): boolean {\n if (typeof root.authoritative_location === 'string') return true;\n if (typeof root.house === 'string') return true;\n\n const hasIdentityFields =\n Array.isArray(root.brands) ||\n Array.isArray(root.logos) ||\n typeof root.domain === 'string' ||\n typeof root.name === 'string' ||\n typeof root.brand_name === 'string' ||\n Array.isArray(root.names);\n\n return Array.isArray(root.agents) && !hasIdentityFields;\n}\n\nfunction isTopLevelBrandIdentity(root: BrandJsonRecord): boolean {\n return (\n typeof root.domain === 'string' ||\n typeof root.name === 'string' ||\n typeof root.brand_name === 'string' ||\n Array.isArray(root.names)\n );\n}\n\nfunction isRecord(value: unknown): value is BrandJsonRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readLocalizedName(value: unknown): string | undefined {\n if (!Array.isArray(value)) return undefined;\n\n for (const entry of value) {\n if (!isRecord(entry)) continue;\n if (typeof entry.en === 'string' && entry.en.trim()) return entry.en;\n for (const name of Object.values(entry)) {\n if (typeof name === 'string' && name.trim()) return name;\n }\n }\n\n return undefined;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from
|
|
2
|
-
import { dirname as __adcpDirname } from
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
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 __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));
|
|
5
|
+
const require2 = __adcpCreateRequire(import.meta.url);
|
|
7
6
|
import { createHash } from "crypto";
|
|
8
7
|
import Ajv from "ajv";
|
|
9
|
-
const Ajv2020 =
|
|
8
|
+
const Ajv2020 = require2("ajv/dist/2020");
|
|
10
9
|
import addFormats from "ajv-formats";
|
|
11
10
|
import { ssrfSafeFetch, SSRF_TRANSIENT_CODES, SsrfRefusedError } from "../net/ssrf-fetch.mjs";
|
|
12
11
|
import {
|