@adcp/sdk 12.0.0 → 12.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/adapters/content-standards-adapter.mjs +0 -6
- package/dist/lib/adapters/content-standards-adapter.mjs.map +1 -1
- package/dist/lib/adapters/derived-account-store.mjs +0 -6
- package/dist/lib/adapters/derived-account-store.mjs.map +1 -1
- package/dist/lib/adapters/governance-adapter.mjs +0 -6
- package/dist/lib/adapters/governance-adapter.mjs.map +1 -1
- package/dist/lib/adapters/implicit-account-store.mjs +0 -6
- package/dist/lib/adapters/implicit-account-store.mjs.map +1 -1
- package/dist/lib/adapters/index.mjs +0 -6
- package/dist/lib/adapters/index.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/get_products.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/get_products.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/index.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/index.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/types.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs.map +1 -1
- package/dist/lib/adapters/oauth-passthrough-resolver.mjs +0 -6
- package/dist/lib/adapters/oauth-passthrough-resolver.mjs.map +1 -1
- package/dist/lib/adapters/property-list-adapter.mjs +0 -6
- package/dist/lib/adapters/property-list-adapter.mjs.map +1 -1
- package/dist/lib/adapters/roster-account-store.mjs +0 -6
- package/dist/lib/adapters/roster-account-store.mjs.map +1 -1
- package/dist/lib/adapters/si-session-manager.mjs +0 -6
- package/dist/lib/adapters/si-session-manager.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/brand-fields.mjs +0 -6
- package/dist/lib/adapters/version/3.0/brand-fields.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/get-products.mjs +0 -6
- package/dist/lib/adapters/version/3.0/get-products.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/index.mjs +0 -6
- package/dist/lib/adapters/version/3.0/index.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/sync-accounts.mjs +0 -6
- package/dist/lib/adapters/version/3.0/sync-accounts.mjs.map +1 -1
- package/dist/lib/adapters/version/index.mjs +0 -6
- package/dist/lib/adapters/version/index.mjs.map +1 -1
- package/dist/lib/adapters/version/types.mjs +0 -6
- package/dist/lib/advanced.mjs +0 -6
- package/dist/lib/advanced.mjs.map +1 -1
- package/dist/lib/agents/index.generated.mjs +0 -6
- package/dist/lib/agents/index.generated.mjs.map +1 -1
- package/dist/lib/auth/index.mjs +0 -6
- package/dist/lib/auth/index.mjs.map +1 -1
- package/dist/lib/auth/oauth/CLIFlowHandler.mjs +0 -6
- package/dist/lib/auth/oauth/CLIFlowHandler.mjs.map +1 -1
- package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs +0 -6
- package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs.map +1 -1
- package/dist/lib/auth/oauth/MCPOAuthProvider.mjs +0 -6
- package/dist/lib/auth/oauth/MCPOAuthProvider.mjs.map +1 -1
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs +0 -6
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs.map +1 -1
- package/dist/lib/auth/oauth/authorization-required.mjs +0 -6
- package/dist/lib/auth/oauth/authorization-required.mjs.map +1 -1
- package/dist/lib/auth/oauth/diagnose.mjs +0 -6
- package/dist/lib/auth/oauth/diagnose.mjs.map +1 -1
- package/dist/lib/auth/oauth/diagnostics.mjs +0 -6
- package/dist/lib/auth/oauth/diagnostics.mjs.map +1 -1
- package/dist/lib/auth/oauth/discovery.mjs +0 -6
- package/dist/lib/auth/oauth/discovery.mjs.map +1 -1
- package/dist/lib/auth/oauth/file-storage.mjs +0 -6
- package/dist/lib/auth/oauth/file-storage.mjs.map +1 -1
- package/dist/lib/auth/oauth/index.mjs +0 -6
- package/dist/lib/auth/oauth/index.mjs.map +1 -1
- package/dist/lib/auth/oauth/secret-resolver.mjs +0 -6
- package/dist/lib/auth/oauth/secret-resolver.mjs.map +1 -1
- package/dist/lib/auth/oauth/storage-registry.mjs +0 -6
- package/dist/lib/auth/oauth/storage-registry.mjs.map +1 -1
- package/dist/lib/auth/oauth/types.mjs +0 -6
- package/dist/lib/auth/oauth/types.mjs.map +1 -1
- package/dist/lib/auth/oauth/web-flow.mjs +0 -6
- package/dist/lib/auth/oauth/web-flow.mjs.map +1 -1
- package/dist/lib/brand/index.mjs +0 -6
- package/dist/lib/brand/index.mjs.map +1 -1
- package/dist/lib/canonical-references/index.mjs +6 -7
- package/dist/lib/canonical-references/index.mjs.map +1 -1
- package/dist/lib/client/index.mjs +0 -6
- package/dist/lib/client/index.mjs.map +1 -1
- package/dist/lib/compliance/index.mjs +0 -6
- package/dist/lib/compliance/index.mjs.map +1 -1
- package/dist/lib/compliance-fixtures/index.mjs +0 -6
- package/dist/lib/compliance-fixtures/index.mjs.map +1 -1
- package/dist/lib/compliance-fixtures/test-authorization-server.mjs +0 -6
- package/dist/lib/compliance-fixtures/test-authorization-server.mjs.map +1 -1
- package/dist/lib/conformance/index.mjs +0 -6
- package/dist/lib/conformance/index.mjs.map +1 -1
- package/dist/lib/conformance/invariants/uniformError.mjs +0 -6
- package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
- package/dist/lib/conformance/invariants/uniformErrorComparator.mjs +0 -6
- package/dist/lib/conformance/invariants/uniformErrorComparator.mjs.map +1 -1
- package/dist/lib/conformance/oracle.mjs +0 -6
- package/dist/lib/conformance/oracle.mjs.map +1 -1
- package/dist/lib/conformance/runConformance.mjs +0 -6
- package/dist/lib/conformance/runConformance.mjs.map +1 -1
- package/dist/lib/conformance/runners.mjs +0 -6
- package/dist/lib/conformance/runners.mjs.map +1 -1
- package/dist/lib/conformance/schemaArbitrary.mjs +0 -6
- package/dist/lib/conformance/schemaArbitrary.mjs.map +1 -1
- package/dist/lib/conformance/schemaLoader.mjs +5 -6
- package/dist/lib/conformance/schemaLoader.mjs.map +1 -1
- package/dist/lib/conformance/seeder.mjs +0 -6
- package/dist/lib/conformance/seeder.mjs.map +1 -1
- package/dist/lib/conformance/types.mjs +0 -6
- package/dist/lib/conformance/types.mjs.map +1 -1
- package/dist/lib/conformance/webhook.mjs +0 -6
- package/dist/lib/conformance/webhook.mjs.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.mjs +0 -6
- package/dist/lib/core/ADCPMultiAgentClient.mjs.map +1 -1
- package/dist/lib/core/AgentClient.mjs +0 -6
- package/dist/lib/core/AgentClient.mjs.map +1 -1
- package/dist/lib/core/AsyncHandler.mjs +0 -6
- package/dist/lib/core/AsyncHandler.mjs.map +1 -1
- package/dist/lib/core/ConfigurationManager.mjs +0 -6
- package/dist/lib/core/ConfigurationManager.mjs.map +1 -1
- package/dist/lib/core/ConversationTypes.mjs +0 -6
- package/dist/lib/core/CreativeAgentClient.mjs +0 -6
- package/dist/lib/core/CreativeAgentClient.mjs.map +1 -1
- package/dist/lib/core/GovernanceMiddleware.mjs +0 -6
- package/dist/lib/core/GovernanceMiddleware.mjs.map +1 -1
- package/dist/lib/core/GovernanceTypes.mjs +0 -6
- package/dist/lib/core/GovernanceTypes.mjs.map +1 -1
- package/dist/lib/core/ProtocolResponseParser.mjs +0 -6
- package/dist/lib/core/ProtocolResponseParser.mjs.map +1 -1
- package/dist/lib/core/ResponseValidator.mjs +0 -6
- package/dist/lib/core/ResponseValidator.mjs.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +0 -6
- package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
- package/dist/lib/core/TaskEventTypes.mjs +0 -6
- package/dist/lib/core/TaskEventTypes.mjs.map +1 -1
- package/dist/lib/core/TaskExecutor.mjs +0 -6
- package/dist/lib/core/TaskExecutor.mjs.map +1 -1
- package/dist/lib/core/match.mjs +0 -6
- package/dist/lib/core/match.mjs.map +1 -1
- package/dist/lib/core/task-status.mjs +0 -6
- package/dist/lib/core/task-status.mjs.map +1 -1
- package/dist/lib/core/webhook-url.mjs +0 -6
- package/dist/lib/core/webhook-url.mjs.map +1 -1
- package/dist/lib/discovery/adagents-redirects.mjs +0 -6
- package/dist/lib/discovery/adagents-redirects.mjs.map +1 -1
- package/dist/lib/discovery/agent-directory.mjs +0 -6
- package/dist/lib/discovery/agent-directory.mjs.map +1 -1
- package/dist/lib/discovery/inline-publisher-properties.mjs +0 -6
- package/dist/lib/discovery/inline-publisher-properties.mjs.map +1 -1
- package/dist/lib/discovery/network-consistency-checker.mjs +0 -6
- package/dist/lib/discovery/network-consistency-checker.mjs.map +1 -1
- package/dist/lib/discovery/property-crawler.mjs +0 -6
- package/dist/lib/discovery/property-crawler.mjs.map +1 -1
- package/dist/lib/discovery/property-index.mjs +0 -6
- package/dist/lib/discovery/property-index.mjs.map +1 -1
- package/dist/lib/discovery/publisher-property-selector.mjs +0 -6
- package/dist/lib/discovery/publisher-property-selector.mjs.map +1 -1
- package/dist/lib/discovery/resolve-agent-properties.mjs +0 -6
- package/dist/lib/discovery/resolve-agent-properties.mjs.map +1 -1
- package/dist/lib/discovery/types.mjs +0 -6
- package/dist/lib/discovery/validate-adagents.mjs +0 -6
- package/dist/lib/discovery/validate-adagents.mjs.map +1 -1
- package/dist/lib/enums.mjs +0 -6
- package/dist/lib/enums.mjs.map +1 -1
- package/dist/lib/errors/index.mjs +0 -6
- package/dist/lib/errors/index.mjs.map +1 -1
- package/dist/lib/express-mcp/index.mjs +0 -6
- package/dist/lib/express-mcp/index.mjs.map +1 -1
- package/dist/lib/governance/index.mjs +0 -6
- package/dist/lib/governance/index.mjs.map +1 -1
- package/dist/lib/handlers/types.mjs +0 -6
- package/dist/lib/handlers/types.mjs.map +1 -1
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +0 -6
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/media-buy/available-actions.mjs +0 -6
- package/dist/lib/media-buy/available-actions.mjs.map +1 -1
- package/dist/lib/media-buy/index.mjs +0 -6
- package/dist/lib/media-buy/index.mjs.map +1 -1
- package/dist/lib/media-buy/preflight.mjs +0 -6
- package/dist/lib/media-buy/preflight.mjs.map +1 -1
- package/dist/lib/media-buy/property-policy.mjs +0 -6
- package/dist/lib/media-buy/property-policy.mjs.map +1 -1
- package/dist/lib/media-buy/types.mjs +0 -6
- package/dist/lib/media-buy/types.mjs.map +1 -1
- package/dist/lib/media-buy/update-fields.generated.mjs +0 -6
- package/dist/lib/media-buy/update-fields.generated.mjs.map +1 -1
- package/dist/lib/mock-server/creative-ad-server/seed-data.mjs +0 -6
- package/dist/lib/mock-server/creative-ad-server/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/creative-ad-server/server.mjs +0 -6
- package/dist/lib/mock-server/creative-ad-server/server.mjs.map +1 -1
- package/dist/lib/mock-server/creative-template/seed-data.mjs +0 -6
- package/dist/lib/mock-server/creative-template/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/creative-template/server.mjs +0 -6
- package/dist/lib/mock-server/creative-template/server.mjs.map +1 -1
- package/dist/lib/mock-server/index.mjs +0 -6
- package/dist/lib/mock-server/index.mjs.map +1 -1
- package/dist/lib/mock-server/sales-guaranteed/recipe.mjs +0 -6
- package/dist/lib/mock-server/sales-guaranteed/recipe.mjs.map +1 -1
- package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sales-guaranteed/server.mjs +0 -6
- package/dist/lib/mock-server/sales-guaranteed/server.mjs.map +1 -1
- package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs +0 -6
- package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs.map +1 -1
- package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sales-non-guaranteed/server.mjs +0 -6
- package/dist/lib/mock-server/sales-non-guaranteed/server.mjs.map +1 -1
- package/dist/lib/mock-server/sales-social/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sales-social/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sales-social/server.mjs +0 -6
- package/dist/lib/mock-server/sales-social/server.mjs.map +1 -1
- package/dist/lib/mock-server/scenario.mjs +0 -6
- package/dist/lib/mock-server/scenario.mjs.map +1 -1
- package/dist/lib/mock-server/signal-marketplace/seed-data.mjs +0 -6
- package/dist/lib/mock-server/signal-marketplace/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/signal-marketplace/server.mjs +0 -6
- package/dist/lib/mock-server/signal-marketplace/server.mjs.map +1 -1
- package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sponsored-intelligence/server.mjs +0 -6
- package/dist/lib/mock-server/sponsored-intelligence/server.mjs.map +1 -1
- package/dist/lib/net/address-guards.mjs +0 -6
- package/dist/lib/net/address-guards.mjs.map +1 -1
- package/dist/lib/net/index.mjs +0 -6
- package/dist/lib/net/index.mjs.map +1 -1
- package/dist/lib/net/ssrf-fetch.mjs +0 -6
- package/dist/lib/net/ssrf-fetch.mjs.map +1 -1
- package/dist/lib/observability/index.mjs +0 -6
- package/dist/lib/observability/index.mjs.map +1 -1
- package/dist/lib/observability/tracing.mjs +6 -7
- package/dist/lib/observability/tracing.mjs.map +1 -1
- package/dist/lib/protocols/a2a.mjs +0 -6
- package/dist/lib/protocols/a2a.mjs.map +1 -1
- package/dist/lib/protocols/abort.mjs +0 -6
- package/dist/lib/protocols/abort.mjs.map +1 -1
- package/dist/lib/protocols/index.mjs +0 -6
- package/dist/lib/protocols/index.mjs.map +1 -1
- package/dist/lib/protocols/mcp-modern.mjs +0 -6
- package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
- package/dist/lib/protocols/mcp-tasks.mjs +0 -6
- package/dist/lib/protocols/mcp-tasks.mjs.map +1 -1
- package/dist/lib/protocols/mcp.mjs +0 -6
- package/dist/lib/protocols/mcp.mjs.map +1 -1
- package/dist/lib/protocols/rawResponseCapture.mjs +0 -6
- package/dist/lib/protocols/rawResponseCapture.mjs.map +1 -1
- package/dist/lib/protocols/responseSizeLimit.mjs +0 -6
- package/dist/lib/protocols/responseSizeLimit.mjs.map +1 -1
- package/dist/lib/protocols/transportDiagnostics.mjs +0 -6
- package/dist/lib/protocols/transportDiagnostics.mjs.map +1 -1
- package/dist/lib/registry/cursor-store.mjs +0 -6
- package/dist/lib/registry/cursor-store.mjs.map +1 -1
- package/dist/lib/registry/feed-stream.mjs +0 -6
- package/dist/lib/registry/feed-stream.mjs.map +1 -1
- package/dist/lib/registry/index.mjs +0 -6
- package/dist/lib/registry/index.mjs.map +1 -1
- package/dist/lib/registry/property-registry.mjs +0 -6
- package/dist/lib/registry/property-registry.mjs.map +1 -1
- package/dist/lib/registry/sync.mjs +0 -6
- package/dist/lib/registry/sync.mjs.map +1 -1
- package/dist/lib/registry/types.generated.mjs +0 -6
- package/dist/lib/registry/types.mjs +0 -6
- package/dist/lib/schemas/index.mjs +0 -6
- package/dist/lib/schemas/index.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/a2a-adapter.mjs +0 -6
- package/dist/lib/server/a2a-adapter.mjs.map +1 -1
- package/dist/lib/server/account-mode.mjs +0 -6
- package/dist/lib/server/account-mode.mjs.map +1 -1
- package/dist/lib/server/adcp-server.mjs +0 -6
- package/dist/lib/server/adcp-server.mjs.map +1 -1
- package/dist/lib/server/auth-introspection.mjs +0 -6
- package/dist/lib/server/auth-introspection.mjs.map +1 -1
- package/dist/lib/server/auth-signature.mjs +0 -6
- package/dist/lib/server/auth-signature.mjs.map +1 -1
- package/dist/lib/server/auth.mjs +0 -6
- package/dist/lib/server/auth.mjs.map +1 -1
- package/dist/lib/server/create-adcp-server.d.mts +13 -0
- package/dist/lib/server/create-adcp-server.d.ts +13 -0
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +3 -2
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/create-adcp-server.mjs +3 -8
- package/dist/lib/server/create-adcp-server.mjs.map +1 -1
- package/dist/lib/server/credential-policy.mjs +0 -6
- package/dist/lib/server/credential-policy.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/backends/memory.mjs +0 -6
- package/dist/lib/server/ctx-metadata/backends/memory.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/backends/pg.mjs +0 -6
- package/dist/lib/server/ctx-metadata/backends/pg.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/backends/redis.mjs +0 -6
- package/dist/lib/server/ctx-metadata/backends/redis.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/index.mjs +0 -6
- package/dist/lib/server/ctx-metadata/index.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/store.mjs +0 -6
- package/dist/lib/server/ctx-metadata/store.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/wire-shape.mjs +0 -6
- package/dist/lib/server/ctx-metadata/wire-shape.mjs.map +1 -1
- package/dist/lib/server/decisioning/account.mjs +0 -6
- package/dist/lib/server/decisioning/account.mjs.map +1 -1
- package/dist/lib/server/decisioning/admin-router.mjs +0 -6
- package/dist/lib/server/decisioning/admin-router.mjs.map +1 -1
- package/dist/lib/server/decisioning/assembly-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/assembly-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/async-outcome.mjs +0 -6
- package/dist/lib/server/decisioning/async-outcome.mjs.map +1 -1
- package/dist/lib/server/decisioning/buyer-agent.mjs +0 -6
- package/dist/lib/server/decisioning/buyer-agent.mjs.map +1 -1
- package/dist/lib/server/decisioning/capabilities.mjs +0 -6
- package/dist/lib/server/decisioning/capabilities.mjs.map +1 -1
- package/dist/lib/server/decisioning/compose.mjs +0 -6
- package/dist/lib/server/decisioning/compose.mjs.map +1 -1
- package/dist/lib/server/decisioning/context.mjs +0 -6
- package/dist/lib/server/decisioning/errors-typed.mjs +0 -6
- package/dist/lib/server/decisioning/errors-typed.mjs.map +1 -1
- package/dist/lib/server/decisioning/helpers.mjs +0 -6
- package/dist/lib/server/decisioning/helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/index.mjs +0 -6
- package/dist/lib/server/decisioning/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/list-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/list-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/manifest-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/manifest-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/pagination.mjs +0 -6
- package/dist/lib/server/decisioning/platform-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/platform-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/platform.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/dispatch.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/dispatch.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/index.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/lifecycle.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/lifecycle.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/mock-manager.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/mock-manager.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/store.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/store.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/types.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/types.mjs.map +1 -1
- package/dist/lib/server/decisioning/resolve-presets.mjs +0 -6
- package/dist/lib/server/decisioning/resolve-presets.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/observed-modes.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/observed-modes.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/task-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/to-context.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/validate-platform.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/validate-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/specialisms/audiences.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/brand-rights.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/campaign-governance.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/content-standards.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/creative.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/lists.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/sales.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/signals.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/sponsored-intelligence.mjs +0 -6
- package/dist/lib/server/decisioning/start-time.mjs +0 -6
- package/dist/lib/server/decisioning/start-time.mjs.map +1 -1
- package/dist/lib/server/decisioning/status-changes.mjs +0 -6
- package/dist/lib/server/decisioning/status-changes.mjs.map +1 -1
- package/dist/lib/server/decisioning/status-mappers.mjs +0 -6
- package/dist/lib/server/decisioning/status-mappers.mjs.map +1 -1
- package/dist/lib/server/decisioning/tenant-registry.mjs +0 -6
- package/dist/lib/server/decisioning/tenant-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/tenant-store.mjs +0 -6
- package/dist/lib/server/decisioning/tenant-store.mjs.map +1 -1
- package/dist/lib/server/decisioning/validate-specialisms.mjs +0 -6
- package/dist/lib/server/decisioning/validate-specialisms.mjs.map +1 -1
- package/dist/lib/server/dynamic-registry.mjs +0 -6
- package/dist/lib/server/dynamic-registry.mjs.map +1 -1
- package/dist/lib/server/envelope-allowlist.mjs +0 -6
- package/dist/lib/server/envelope-allowlist.mjs.map +1 -1
- package/dist/lib/server/error-arm-tools.mjs +5 -6
- package/dist/lib/server/error-arm-tools.mjs.map +1 -1
- package/dist/lib/server/errors.mjs +0 -6
- package/dist/lib/server/errors.mjs.map +1 -1
- package/dist/lib/server/example-tld-guard.mjs +0 -6
- package/dist/lib/server/example-tld-guard.mjs.map +1 -1
- package/dist/lib/server/express-adapter.mjs +0 -6
- package/dist/lib/server/express-adapter.mjs.map +1 -1
- package/dist/lib/server/governance.mjs +0 -6
- package/dist/lib/server/governance.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/lazy.mjs +0 -6
- package/dist/lib/server/idempotency/backends/lazy.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/memory.mjs +0 -6
- package/dist/lib/server/idempotency/backends/memory.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/pg.mjs +0 -6
- package/dist/lib/server/idempotency/backends/pg.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/redis.mjs +0 -6
- package/dist/lib/server/idempotency/backends/redis.mjs.map +1 -1
- package/dist/lib/server/idempotency/index.mjs +0 -6
- package/dist/lib/server/idempotency/index.mjs.map +1 -1
- package/dist/lib/server/idempotency/store.mjs +0 -6
- package/dist/lib/server/idempotency/store.mjs.map +1 -1
- package/dist/lib/server/index.d.mts +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/index.mjs +0 -6
- package/dist/lib/server/index.mjs.map +1 -1
- package/dist/lib/server/legacy/v5/index.d.mts +1 -1
- package/dist/lib/server/legacy/v5/index.d.ts +1 -1
- package/dist/lib/server/legacy/v5/index.d.ts.map +1 -1
- package/dist/lib/server/legacy/v5/index.js.map +1 -1
- package/dist/lib/server/legacy/v5/index.mjs +0 -6
- package/dist/lib/server/legacy/v5/index.mjs.map +1 -1
- package/dist/lib/server/mcp-modern-server.mjs +0 -6
- package/dist/lib/server/mcp-modern-server.mjs.map +1 -1
- package/dist/lib/server/media-buy-actions.mjs +0 -6
- package/dist/lib/server/media-buy-actions.mjs.map +1 -1
- package/dist/lib/server/media-buy-helpers.mjs +0 -6
- package/dist/lib/server/media-buy-helpers.mjs.map +1 -1
- package/dist/lib/server/media-buy-store.mjs +0 -6
- package/dist/lib/server/media-buy-store.mjs.map +1 -1
- package/dist/lib/server/normalize-errors.mjs +0 -6
- package/dist/lib/server/normalize-errors.mjs.map +1 -1
- package/dist/lib/server/operational-platform.mjs +0 -6
- package/dist/lib/server/operational-platform.mjs.map +1 -1
- package/dist/lib/server/pick-safe-details.mjs +0 -6
- package/dist/lib/server/pick-safe-details.mjs.map +1 -1
- package/dist/lib/server/pin-and-bind-fetch.mjs +0 -6
- package/dist/lib/server/pin-and-bind-fetch.mjs.map +1 -1
- package/dist/lib/server/postgres-state-store.mjs +0 -6
- package/dist/lib/server/postgres-state-store.mjs.map +1 -1
- package/dist/lib/server/postgres-task-store.mjs +0 -6
- package/dist/lib/server/postgres-task-store.mjs.map +1 -1
- package/dist/lib/server/product-defaults.mjs +0 -6
- package/dist/lib/server/product-defaults.mjs.map +1 -1
- package/dist/lib/server/redact.mjs +0 -6
- package/dist/lib/server/redact.mjs.map +1 -1
- package/dist/lib/server/responses.mjs +0 -6
- package/dist/lib/server/responses.mjs.map +1 -1
- package/dist/lib/server/serve.mjs +0 -6
- package/dist/lib/server/serve.mjs.map +1 -1
- package/dist/lib/server/socket-mode/conformance-client.mjs +0 -6
- package/dist/lib/server/socket-mode/conformance-client.mjs.map +1 -1
- package/dist/lib/server/socket-mode/index.mjs +0 -6
- package/dist/lib/server/socket-mode/index.mjs.map +1 -1
- package/dist/lib/server/socket-mode/ws-transport.mjs +0 -6
- package/dist/lib/server/socket-mode/ws-transport.mjs.map +1 -1
- package/dist/lib/server/state-machine.mjs +0 -6
- package/dist/lib/server/state-machine.mjs.map +1 -1
- package/dist/lib/server/state-store.mjs +0 -6
- package/dist/lib/server/state-store.mjs.map +1 -1
- package/dist/lib/server/structured-serialize.mjs +0 -6
- package/dist/lib/server/structured-serialize.mjs.map +1 -1
- package/dist/lib/server/targeting-helpers.mjs +0 -6
- package/dist/lib/server/targeting-helpers.mjs.map +1 -1
- package/dist/lib/server/tasks.mjs +0 -6
- package/dist/lib/server/tasks.mjs.map +1 -1
- package/dist/lib/server/test-controller-bridge.mjs +0 -6
- package/dist/lib/server/test-controller-bridge.mjs.map +1 -1
- package/dist/lib/server/test-controller.mjs +0 -6
- package/dist/lib/server/test-controller.mjs.map +1 -1
- package/dist/lib/server/upstream-helpers.mjs +0 -6
- package/dist/lib/server/upstream-helpers.mjs.map +1 -1
- package/dist/lib/server/webhook-emitter.mjs +0 -6
- package/dist/lib/server/webhook-emitter.mjs.map +1 -1
- package/dist/lib/server/wire-safe.mjs +0 -6
- package/dist/lib/server/wire-safe.mjs.map +1 -1
- package/dist/lib/server/wire-spec-fields.generated.mjs +0 -6
- package/dist/lib/server/wire-spec-fields.generated.mjs.map +1 -1
- package/dist/lib/server/wrap-envelope.mjs +0 -6
- package/dist/lib/server/wrap-envelope.mjs.map +1 -1
- package/dist/lib/signing/agent-context.mjs +0 -6
- package/dist/lib/signing/agent-context.mjs.map +1 -1
- package/dist/lib/signing/agent-fetch.mjs +0 -6
- package/dist/lib/signing/agent-fetch.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/canonicalize.mjs +0 -6
- package/dist/lib/signing/agent-resolver/canonicalize.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/capabilities-types.mjs +0 -6
- package/dist/lib/signing/agent-resolver/capabilities-types.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/consistency.mjs +0 -6
- package/dist/lib/signing/agent-resolver/consistency.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/errors.mjs +0 -6
- package/dist/lib/signing/agent-resolver/errors.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/etld.mjs +0 -6
- package/dist/lib/signing/agent-resolver/etld.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +0 -6
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/index.mjs +0 -6
- package/dist/lib/signing/agent-resolver/index.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/jwks-set.mjs +0 -6
- package/dist/lib/signing/agent-resolver/jwks-set.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs +0 -6
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/select-agent.mjs +0 -6
- package/dist/lib/signing/agent-resolver/select-agent.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/strict-json.mjs +0 -6
- package/dist/lib/signing/agent-resolver/strict-json.mjs.map +1 -1
- package/dist/lib/signing/brand-jwks.mjs +0 -6
- package/dist/lib/signing/brand-jwks.mjs.map +1 -1
- package/dist/lib/signing/canonicalize.mjs +0 -6
- package/dist/lib/signing/canonicalize.mjs.map +1 -1
- package/dist/lib/signing/capability-cache.mjs +0 -6
- package/dist/lib/signing/capability-cache.mjs.map +1 -1
- package/dist/lib/signing/capability-priming.mjs +0 -6
- package/dist/lib/signing/capability-priming.mjs.map +1 -1
- package/dist/lib/signing/client.mjs +0 -6
- package/dist/lib/signing/client.mjs.map +1 -1
- package/dist/lib/signing/content-digest.mjs +0 -6
- package/dist/lib/signing/content-digest.mjs.map +1 -1
- package/dist/lib/signing/crypto.mjs +0 -6
- package/dist/lib/signing/crypto.mjs.map +1 -1
- package/dist/lib/signing/ecdsa-encoding.mjs +0 -6
- package/dist/lib/signing/ecdsa-encoding.mjs.map +1 -1
- package/dist/lib/signing/errors.mjs +0 -6
- package/dist/lib/signing/errors.mjs.map +1 -1
- package/dist/lib/signing/fetch-async.mjs +0 -6
- package/dist/lib/signing/fetch-async.mjs.map +1 -1
- package/dist/lib/signing/fetch.mjs +0 -6
- package/dist/lib/signing/fetch.mjs.map +1 -1
- package/dist/lib/signing/index.mjs +0 -6
- package/dist/lib/signing/index.mjs.map +1 -1
- package/dist/lib/signing/jwks-helpers.mjs +0 -6
- package/dist/lib/signing/jwks-helpers.mjs.map +1 -1
- package/dist/lib/signing/jwks-https.mjs +0 -6
- package/dist/lib/signing/jwks-https.mjs.map +1 -1
- package/dist/lib/signing/jwks.mjs +0 -6
- package/dist/lib/signing/jwks.mjs.map +1 -1
- package/dist/lib/signing/middleware.mjs +0 -6
- package/dist/lib/signing/middleware.mjs.map +1 -1
- package/dist/lib/signing/parser.mjs +0 -6
- package/dist/lib/signing/parser.mjs.map +1 -1
- package/dist/lib/signing/postgres-replay-store.mjs +0 -6
- package/dist/lib/signing/postgres-replay-store.mjs.map +1 -1
- package/dist/lib/signing/protocol-response.mjs +0 -6
- package/dist/lib/signing/protocol-response.mjs.map +1 -1
- package/dist/lib/signing/provider.mjs +0 -6
- package/dist/lib/signing/redis-replay-store.mjs +0 -6
- package/dist/lib/signing/redis-replay-store.mjs.map +1 -1
- package/dist/lib/signing/replay.mjs +0 -6
- package/dist/lib/signing/replay.mjs.map +1 -1
- package/dist/lib/signing/request-context.mjs +0 -6
- package/dist/lib/signing/request-context.mjs.map +1 -1
- package/dist/lib/signing/revocation-https.mjs +0 -6
- package/dist/lib/signing/revocation-https.mjs.map +1 -1
- package/dist/lib/signing/revocation.mjs +0 -6
- package/dist/lib/signing/revocation.mjs.map +1 -1
- package/dist/lib/signing/server.mjs +0 -6
- package/dist/lib/signing/server.mjs.map +1 -1
- package/dist/lib/signing/signer-async.mjs +0 -6
- package/dist/lib/signing/signer-async.mjs.map +1 -1
- package/dist/lib/signing/signer.mjs +0 -6
- package/dist/lib/signing/signer.mjs.map +1 -1
- package/dist/lib/signing/testing.mjs +0 -6
- package/dist/lib/signing/testing.mjs.map +1 -1
- package/dist/lib/signing/types.mjs +0 -6
- package/dist/lib/signing/types.mjs.map +1 -1
- package/dist/lib/signing/verifier.mjs +0 -6
- package/dist/lib/signing/verifier.mjs.map +1 -1
- package/dist/lib/signing/webhook-auth-detection.mjs +0 -6
- package/dist/lib/signing/webhook-auth-detection.mjs.map +1 -1
- package/dist/lib/signing/webhook-verifier.mjs +0 -6
- package/dist/lib/signing/webhook-verifier.mjs.map +1 -1
- package/dist/lib/storage/MemoryStorage.mjs +0 -6
- package/dist/lib/storage/MemoryStorage.mjs.map +1 -1
- package/dist/lib/storage/interfaces.mjs +0 -6
- package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs +0 -6
- package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs.map +1 -1
- package/dist/lib/substitution/encoder/index.mjs +0 -6
- package/dist/lib/substitution/encoder/index.mjs.map +1 -1
- package/dist/lib/substitution/index.mjs +0 -6
- package/dist/lib/substitution/index.mjs.map +1 -1
- package/dist/lib/substitution/observer/SubstitutionObserver.mjs +0 -6
- package/dist/lib/substitution/observer/SubstitutionObserver.mjs.map +1 -1
- package/dist/lib/substitution/observer/alignment.mjs +0 -6
- package/dist/lib/substitution/observer/alignment.mjs.map +1 -1
- package/dist/lib/substitution/observer/assertions.mjs +0 -6
- package/dist/lib/substitution/observer/assertions.mjs.map +1 -1
- package/dist/lib/substitution/observer/html-parser.mjs +0 -6
- package/dist/lib/substitution/observer/html-parser.mjs.map +1 -1
- package/dist/lib/substitution/observer/index.mjs +0 -6
- package/dist/lib/substitution/observer/index.mjs.map +1 -1
- package/dist/lib/substitution/observer/ssrf.mjs +0 -6
- package/dist/lib/substitution/observer/ssrf.mjs.map +1 -1
- package/dist/lib/substitution/rfc3986.mjs +0 -6
- package/dist/lib/substitution/rfc3986.mjs.map +1 -1
- package/dist/lib/substitution/translate.mjs +0 -6
- package/dist/lib/substitution/translate.mjs.map +1 -1
- package/dist/lib/substitution/types.mjs +0 -6
- package/dist/lib/substitution/vectors.mjs +0 -6
- package/dist/lib/substitution/vectors.mjs.map +1 -1
- package/dist/lib/testing/agent-tester.mjs +0 -6
- package/dist/lib/testing/agent-tester.mjs.map +1 -1
- package/dist/lib/testing/client.mjs +0 -6
- package/dist/lib/testing/client.mjs.map +1 -1
- package/dist/lib/testing/compliance/briefs.mjs +0 -6
- package/dist/lib/testing/compliance/briefs.mjs.map +1 -1
- package/dist/lib/testing/compliance/comply.mjs +0 -6
- package/dist/lib/testing/compliance/comply.mjs.map +1 -1
- package/dist/lib/testing/compliance/index.mjs +0 -6
- package/dist/lib/testing/compliance/index.mjs.map +1 -1
- package/dist/lib/testing/compliance/spec-conformance.mjs +0 -6
- package/dist/lib/testing/compliance/spec-conformance.mjs.map +1 -1
- package/dist/lib/testing/compliance/storyboard-tracks.mjs +0 -6
- package/dist/lib/testing/compliance/storyboard-tracks.mjs.map +1 -1
- package/dist/lib/testing/compliance/summary.mjs +0 -6
- package/dist/lib/testing/compliance/summary.mjs.map +1 -1
- package/dist/lib/testing/compliance/types.mjs +0 -6
- package/dist/lib/testing/comply-controller.mjs +0 -6
- package/dist/lib/testing/comply-controller.mjs.map +1 -1
- package/dist/lib/testing/controller-assertions.mjs +0 -6
- package/dist/lib/testing/controller-assertions.mjs.map +1 -1
- package/dist/lib/testing/formatter.mjs +0 -6
- package/dist/lib/testing/formatter.mjs.map +1 -1
- package/dist/lib/testing/index.mjs +0 -6
- package/dist/lib/testing/index.mjs.map +1 -1
- package/dist/lib/testing/local-agent-runner.mjs +0 -6
- package/dist/lib/testing/local-agent-runner.mjs.map +1 -1
- package/dist/lib/testing/orchestrator.mjs +0 -6
- package/dist/lib/testing/orchestrator.mjs.map +1 -1
- package/dist/lib/testing/personas/index.mjs +0 -6
- package/dist/lib/testing/personas/index.mjs.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.mjs +0 -6
- package/dist/lib/testing/scenarios/brand-rights.mjs.map +1 -1
- package/dist/lib/testing/scenarios/capabilities.mjs +0 -6
- package/dist/lib/testing/scenarios/capabilities.mjs.map +1 -1
- package/dist/lib/testing/scenarios/creative.mjs +0 -6
- package/dist/lib/testing/scenarios/creative.mjs.map +1 -1
- package/dist/lib/testing/scenarios/deterministic.mjs +0 -6
- package/dist/lib/testing/scenarios/deterministic.mjs.map +1 -1
- package/dist/lib/testing/scenarios/discovery.mjs +0 -6
- package/dist/lib/testing/scenarios/discovery.mjs.map +1 -1
- package/dist/lib/testing/scenarios/edge-cases.mjs +0 -6
- package/dist/lib/testing/scenarios/edge-cases.mjs.map +1 -1
- package/dist/lib/testing/scenarios/error-compliance.mjs +0 -6
- package/dist/lib/testing/scenarios/error-compliance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/governance.mjs +0 -6
- package/dist/lib/testing/scenarios/governance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/health.mjs +0 -6
- package/dist/lib/testing/scenarios/health.mjs.map +1 -1
- package/dist/lib/testing/scenarios/index.mjs +0 -6
- package/dist/lib/testing/scenarios/index.mjs.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.mjs +0 -6
- package/dist/lib/testing/scenarios/media-buy.mjs.map +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.mjs +0 -6
- package/dist/lib/testing/scenarios/schema-compliance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/signals.mjs +0 -6
- package/dist/lib/testing/scenarios/signals.mjs.map +1 -1
- package/dist/lib/testing/scenarios/sponsored-intelligence.mjs +0 -6
- package/dist/lib/testing/scenarios/sponsored-intelligence.mjs.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.mjs +0 -6
- package/dist/lib/testing/scenarios/trusted-match.mjs.map +1 -1
- package/dist/lib/testing/seed-merge.mjs +0 -6
- package/dist/lib/testing/seed-merge.mjs.map +1 -1
- package/dist/lib/testing/storyboard/agent-routing.mjs +0 -6
- package/dist/lib/testing/storyboard/agent-routing.mjs.map +1 -1
- package/dist/lib/testing/storyboard/assertions.mjs +0 -6
- package/dist/lib/testing/storyboard/assertions.mjs.map +1 -1
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +0 -6
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs.map +1 -1
- package/dist/lib/testing/storyboard/compliance.mjs +5 -6
- package/dist/lib/testing/storyboard/compliance.mjs.map +1 -1
- package/dist/lib/testing/storyboard/context.mjs +0 -6
- package/dist/lib/testing/storyboard/context.mjs.map +1 -1
- package/dist/lib/testing/storyboard/default-invariants.mjs +0 -6
- package/dist/lib/testing/storyboard/default-invariants.mjs.map +1 -1
- package/dist/lib/testing/storyboard/index.mjs +0 -6
- package/dist/lib/testing/storyboard/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/junit.mjs +0 -6
- package/dist/lib/testing/storyboard/junit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/loader.mjs +0 -6
- package/dist/lib/testing/storyboard/loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/parallel-dispatch.mjs +0 -6
- package/dist/lib/testing/storyboard/parallel-dispatch.mjs.map +1 -1
- package/dist/lib/testing/storyboard/path.mjs +0 -6
- package/dist/lib/testing/storyboard/path.mjs.map +1 -1
- package/dist/lib/testing/storyboard/probes.mjs +0 -6
- package/dist/lib/testing/storyboard/probes.mjs.map +1 -1
- package/dist/lib/testing/storyboard/rate-limit-trip.mjs +0 -6
- package/dist/lib/testing/storyboard/rate-limit-trip.mjs.map +1 -1
- package/dist/lib/testing/storyboard/rejection-hints.mjs +0 -6
- package/dist/lib/testing/storyboard/rejection-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.mjs +0 -6
- package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/grader.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/grader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/index.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/probe.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/synthesize.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/synthesize.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/test-kit.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/test-kit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/types.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +0 -6
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/sandbox-entities.mjs +0 -6
- package/dist/lib/testing/storyboard/sandbox-entities.mjs.map +1 -1
- package/dist/lib/testing/storyboard/seeding.mjs +0 -6
- package/dist/lib/testing/storyboard/seeding.mjs.map +1 -1
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs +0 -6
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/signer-grader/grader.mjs +0 -6
- package/dist/lib/testing/storyboard/signer-grader/grader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/signer-grader/index.mjs +0 -6
- package/dist/lib/testing/storyboard/signer-grader/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/signer-grader/types.mjs +0 -6
- package/dist/lib/testing/storyboard/strict-validation-hints.mjs +0 -6
- package/dist/lib/testing/storyboard/strict-validation-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/task-map.mjs +0 -6
- package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
- package/dist/lib/testing/storyboard/test-kit.mjs +0 -6
- package/dist/lib/testing/storyboard/test-kit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/types.mjs +0 -6
- package/dist/lib/testing/storyboard/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/validations.mjs +0 -6
- package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
- package/dist/lib/testing/storyboard/webhook-assertions.mjs +0 -6
- package/dist/lib/testing/storyboard/webhook-assertions.mjs.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.mjs +0 -6
- package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
- package/dist/lib/testing/stubs/governance-agent-stub.mjs +0 -6
- package/dist/lib/testing/stubs/governance-agent-stub.mjs.map +1 -1
- package/dist/lib/testing/stubs/index.mjs +0 -6
- package/dist/lib/testing/stubs/index.mjs.map +1 -1
- package/dist/lib/testing/test-controller.mjs +0 -6
- package/dist/lib/testing/test-controller.mjs.map +1 -1
- package/dist/lib/testing/test-helpers.mjs +0 -6
- package/dist/lib/testing/test-helpers.mjs.map +1 -1
- package/dist/lib/testing/types.mjs +0 -6
- package/dist/lib/types/adcp.mjs +0 -6
- package/dist/lib/types/adcp.mjs.map +1 -1
- package/dist/lib/types/asset-instances.mjs +0 -6
- package/dist/lib/types/compat.mjs +0 -6
- package/dist/lib/types/compat.mjs.map +1 -1
- package/dist/lib/types/core.generated.mjs +0 -6
- package/dist/lib/types/enums.generated.mjs +0 -6
- package/dist/lib/types/enums.generated.mjs.map +1 -1
- package/dist/lib/types/error-codes.mjs +0 -6
- package/dist/lib/types/error-codes.mjs.map +1 -1
- package/dist/lib/types/error-details.aliases.mjs +0 -6
- package/dist/lib/types/error-details.aliases.mjs.map +1 -1
- package/dist/lib/types/format-asset-slots.mjs +0 -6
- package/dist/lib/types/forward-compat-error-codes.mjs +0 -6
- package/dist/lib/types/forward-compat-error-codes.mjs.map +1 -1
- package/dist/lib/types/index.mjs +0 -6
- package/dist/lib/types/index.mjs.map +1 -1
- package/dist/lib/types/inline-enums.aliases.mjs +0 -6
- package/dist/lib/types/inline-enums.aliases.mjs.map +1 -1
- package/dist/lib/types/inline-enums.generated.mjs +0 -6
- package/dist/lib/types/inline-enums.generated.mjs.map +1 -1
- package/dist/lib/types/manifest.generated.mjs +0 -6
- package/dist/lib/types/manifest.generated.mjs.map +1 -1
- package/dist/lib/types/schemas.generated.mjs +0 -6
- package/dist/lib/types/schemas.generated.mjs.map +1 -1
- package/dist/lib/types/server-payload-aliases.mjs +0 -6
- package/dist/lib/types/server-payload.mjs +0 -6
- package/dist/lib/types/sync-rows.mjs +0 -6
- package/dist/lib/types/tools.generated.mjs +0 -6
- package/dist/lib/types/v2-5/index.mjs +0 -6
- package/dist/lib/types/v2-5/index.mjs.map +1 -1
- package/dist/lib/types/v2-5/tools.generated.mjs +0 -6
- package/dist/lib/types/v3-1-beta/index.mjs +0 -6
- package/dist/lib/types/v3-1-beta/index.mjs.map +1 -1
- package/dist/lib/types/v3-1-beta/tools.generated.mjs +0 -6
- package/dist/lib/types/wellknown-schemas.generated.mjs +0 -6
- package/dist/lib/types/wellknown-schemas.generated.mjs.map +1 -1
- package/dist/lib/upstream-recorder/constants.mjs +0 -6
- package/dist/lib/upstream-recorder/constants.mjs.map +1 -1
- package/dist/lib/upstream-recorder/index.mjs +0 -6
- package/dist/lib/upstream-recorder/index.mjs.map +1 -1
- package/dist/lib/upstream-recorder/recorder.mjs +0 -6
- package/dist/lib/upstream-recorder/recorder.mjs.map +1 -1
- package/dist/lib/upstream-recorder/types.mjs +0 -6
- package/dist/lib/upstream-recorder/types.mjs.map +1 -1
- package/dist/lib/utils/a2a-artifacts.mjs +0 -6
- package/dist/lib/utils/a2a-artifacts.mjs.map +1 -1
- package/dist/lib/utils/a2a-discovery.mjs +0 -6
- package/dist/lib/utils/a2a-discovery.mjs.map +1 -1
- package/dist/lib/utils/activation-key-builders.mjs +0 -6
- package/dist/lib/utils/activation-key-builders.mjs.map +1 -1
- package/dist/lib/utils/adcp-version-config.mjs +0 -6
- package/dist/lib/utils/adcp-version-config.mjs.map +1 -1
- package/dist/lib/utils/asset-builders.mjs +0 -6
- package/dist/lib/utils/asset-builders.mjs.map +1 -1
- package/dist/lib/utils/build-creative-return-builders.mjs +0 -6
- package/dist/lib/utils/build-creative-return-builders.mjs.map +1 -1
- package/dist/lib/utils/buyer-retry-policy.mjs +0 -6
- package/dist/lib/utils/buyer-retry-policy.mjs.map +1 -1
- package/dist/lib/utils/capabilities.mjs +0 -6
- package/dist/lib/utils/capabilities.mjs.map +1 -1
- package/dist/lib/utils/capability-rollups.mjs +0 -6
- package/dist/lib/utils/capability-rollups.mjs.map +1 -1
- package/dist/lib/utils/creative-adapter.mjs +0 -6
- package/dist/lib/utils/creative-adapter.mjs.map +1 -1
- package/dist/lib/utils/creative-delivery.mjs +0 -6
- package/dist/lib/utils/creative-delivery.mjs.map +1 -1
- package/dist/lib/utils/deprecation.mjs +0 -6
- package/dist/lib/utils/deprecation.mjs.map +1 -1
- package/dist/lib/utils/envelope-status-compat.mjs +0 -6
- package/dist/lib/utils/envelope-status-compat.mjs.map +1 -1
- package/dist/lib/utils/error-extraction.mjs +0 -6
- package/dist/lib/utils/error-extraction.mjs.map +1 -1
- package/dist/lib/utils/extract-result.mjs +0 -6
- package/dist/lib/utils/extract-result.mjs.map +1 -1
- package/dist/lib/utils/format-asset-slot-builders.mjs +0 -6
- package/dist/lib/utils/format-asset-slot-builders.mjs.map +1 -1
- package/dist/lib/utils/format-assets.mjs +0 -6
- package/dist/lib/utils/format-assets.mjs.map +1 -1
- package/dist/lib/utils/format-render-builders.mjs +0 -6
- package/dist/lib/utils/format-render-builders.mjs.map +1 -1
- package/dist/lib/utils/format-renders.mjs +0 -6
- package/dist/lib/utils/format-renders.mjs.map +1 -1
- package/dist/lib/utils/get-products-cache-scope.mjs +0 -6
- package/dist/lib/utils/get-products-cache-scope.mjs.map +1 -1
- package/dist/lib/utils/glob.mjs +0 -6
- package/dist/lib/utils/glob.mjs.map +1 -1
- package/dist/lib/utils/global-async-local-storage.mjs +0 -6
- package/dist/lib/utils/global-async-local-storage.mjs.map +1 -1
- package/dist/lib/utils/idempotency.mjs +0 -6
- package/dist/lib/utils/idempotency.mjs.map +1 -1
- package/dist/lib/utils/index.mjs +0 -6
- package/dist/lib/utils/index.mjs.map +1 -1
- package/dist/lib/utils/jcs.mjs +0 -6
- package/dist/lib/utils/jcs.mjs.map +1 -1
- package/dist/lib/utils/json-depth.mjs +0 -6
- package/dist/lib/utils/json-depth.mjs.map +1 -1
- package/dist/lib/utils/logger.mjs +0 -6
- package/dist/lib/utils/logger.mjs.map +1 -1
- package/dist/lib/utils/media-buy-delivery-notification-builders.mjs +0 -6
- package/dist/lib/utils/media-buy-delivery-notification-builders.mjs.map +1 -1
- package/dist/lib/utils/media-buy-status.mjs +0 -6
- package/dist/lib/utils/media-buy-status.mjs.map +1 -1
- package/dist/lib/utils/pagination.mjs +0 -6
- package/dist/lib/utils/pagination.mjs.map +1 -1
- package/dist/lib/utils/preview-creative-builders.mjs +0 -6
- package/dist/lib/utils/preview-creative-builders.mjs.map +1 -1
- package/dist/lib/utils/preview-normalizer.mjs +0 -6
- package/dist/lib/utils/preview-normalizer.mjs.map +1 -1
- package/dist/lib/utils/preview-utils.mjs +0 -6
- package/dist/lib/utils/preview-utils.mjs.map +1 -1
- package/dist/lib/utils/pricing-adapter.mjs +0 -6
- package/dist/lib/utils/pricing-adapter.mjs.map +1 -1
- package/dist/lib/utils/probe-policy.mjs +0 -6
- package/dist/lib/utils/probe-policy.mjs.map +1 -1
- package/dist/lib/utils/protocol-detection.mjs +0 -6
- package/dist/lib/utils/protocol-detection.mjs.map +1 -1
- package/dist/lib/utils/redact-secrets.mjs +0 -6
- package/dist/lib/utils/redact-secrets.mjs.map +1 -1
- package/dist/lib/utils/redis-default-prefix-warn.mjs +0 -6
- package/dist/lib/utils/redis-default-prefix-warn.mjs.map +1 -1
- package/dist/lib/utils/render-builders.mjs +0 -6
- package/dist/lib/utils/render-builders.mjs.map +1 -1
- package/dist/lib/utils/request-normalizer.mjs +0 -6
- package/dist/lib/utils/request-normalizer.mjs.map +1 -1
- package/dist/lib/utils/response-schemas.mjs +0 -6
- package/dist/lib/utils/response-schemas.mjs.map +1 -1
- package/dist/lib/utils/response-unwrapper.mjs +0 -6
- package/dist/lib/utils/response-unwrapper.mjs.map +1 -1
- package/dist/lib/utils/retry.mjs +0 -6
- package/dist/lib/utils/retry.mjs.map +1 -1
- package/dist/lib/utils/signal-discovery-helpers.mjs +0 -6
- package/dist/lib/utils/signal-discovery-helpers.mjs.map +1 -1
- package/dist/lib/utils/signal-id-builders.mjs +0 -6
- package/dist/lib/utils/signal-id-builders.mjs.map +1 -1
- package/dist/lib/utils/sync-creatives-adapter.mjs +0 -6
- package/dist/lib/utils/sync-creatives-adapter.mjs.map +1 -1
- package/dist/lib/utils/task-state.mjs +0 -6
- package/dist/lib/utils/task-state.mjs.map +1 -1
- package/dist/lib/utils/tool-request-schemas.mjs +0 -6
- package/dist/lib/utils/tool-request-schemas.mjs.map +1 -1
- package/dist/lib/utils/typeGuards.mjs +0 -6
- package/dist/lib/utils/typeGuards.mjs.map +1 -1
- package/dist/lib/utils/union-errors.mjs +0 -6
- package/dist/lib/utils/union-errors.mjs.map +1 -1
- package/dist/lib/utils/validate-user-agent.mjs +0 -6
- package/dist/lib/utils/validate-user-agent.mjs.map +1 -1
- package/dist/lib/v2/format-schema/fetch.mjs +0 -6
- package/dist/lib/v2/format-schema/fetch.mjs.map +1 -1
- package/dist/lib/v2/format-schema/index.mjs +0 -6
- package/dist/lib/v2/format-schema/index.mjs.map +1 -1
- package/dist/lib/v2/format-schema/regex-safety.mjs +0 -6
- package/dist/lib/v2/format-schema/regex-safety.mjs.map +1 -1
- package/dist/lib/v2/format-schema/resolver.mjs +7 -8
- package/dist/lib/v2/format-schema/resolver.mjs.map +1 -1
- package/dist/lib/v2/format-schema/sandbox-refs.mjs +0 -6
- package/dist/lib/v2/format-schema/sandbox-refs.mjs.map +1 -1
- package/dist/lib/v2/projection/augment-response.mjs +0 -6
- package/dist/lib/v2/projection/augment-response.mjs.map +1 -1
- package/dist/lib/v2/projection/builders.mjs +0 -6
- package/dist/lib/v2/projection/builders.mjs.map +1 -1
- package/dist/lib/v2/projection/cache-versions.mjs +0 -6
- package/dist/lib/v2/projection/cache-versions.mjs.map +1 -1
- package/dist/lib/v2/projection/canonical-properties.mjs +5 -6
- package/dist/lib/v2/projection/canonical-properties.mjs.map +1 -1
- package/dist/lib/v2/projection/catalog.mjs +5 -6
- package/dist/lib/v2/projection/catalog.mjs.map +1 -1
- package/dist/lib/v2/projection/constants.mjs +0 -6
- package/dist/lib/v2/projection/constants.mjs.map +1 -1
- package/dist/lib/v2/projection/index.mjs +0 -6
- package/dist/lib/v2/projection/index.mjs.map +1 -1
- package/dist/lib/v2/projection/registry.mjs +5 -6
- package/dist/lib/v2/projection/registry.mjs.map +1 -1
- package/dist/lib/v2/projection/types.mjs +0 -6
- package/dist/lib/v2/projection/v1-to-v2.mjs +0 -6
- package/dist/lib/v2/projection/v1-to-v2.mjs.map +1 -1
- package/dist/lib/v2/projection/v2-to-v1.mjs +0 -6
- package/dist/lib/v2/projection/v2-to-v1.mjs.map +1 -1
- package/dist/lib/v2/projection/write-side.mjs +0 -6
- package/dist/lib/v2/projection/write-side.mjs.map +1 -1
- package/dist/lib/v2/publisher-catalog/formats.mjs +0 -6
- package/dist/lib/v2/publisher-catalog/formats.mjs.map +1 -1
- package/dist/lib/v2/publisher-catalog/index.mjs +0 -6
- package/dist/lib/v2/publisher-catalog/index.mjs.map +1 -1
- package/dist/lib/validation/client-hooks.mjs +0 -6
- package/dist/lib/validation/client-hooks.mjs.map +1 -1
- package/dist/lib/validation/hints.mjs +0 -6
- package/dist/lib/validation/hints.mjs.map +1 -1
- package/dist/lib/validation/index.mjs +0 -6
- package/dist/lib/validation/index.mjs.map +1 -1
- package/dist/lib/validation/schema-errors.mjs +0 -6
- package/dist/lib/validation/schema-errors.mjs.map +1 -1
- package/dist/lib/validation/schema-loader.mjs +5 -6
- package/dist/lib/validation/schema-loader.mjs.map +1 -1
- package/dist/lib/validation/schema-validator.mjs +0 -6
- package/dist/lib/validation/schema-validator.mjs.map +1 -1
- package/dist/lib/validation/sync-creatives.mjs +0 -6
- package/dist/lib/validation/sync-creatives.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -9
- package/dist/lib/version.mjs.map +1 -1
- package/dist/lib/webhooks/index.mjs +0 -6
- package/dist/lib/webhooks/index.mjs.map +1 -1
- package/dist/lib/wholesale-feed-sync/index.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/index.mjs.map +1 -1
- package/dist/lib/wholesale-feed-sync/sync.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/sync.mjs.map +1 -1
- package/dist/lib/wholesale-feed-sync/types.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/webhook-notification.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/webhook-notification.mjs.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/canonical-references/index.ts"],"sourcesContent":["/**\n * Hardened resolver for immutable AdCP canonical references.\n *\n * `format_schema` and `platform_extensions` share the same reference shape:\n * `{ uri, digest }`, where digest is `sha256:` plus a 64-character lowercase\n * hex digest of the fetched body. This module gives callers one security\n * boundary for resolving those references: HTTPS-only by default, DNS-pinned\n * SSRF-safe fetches, redirects disabled, body and timeout caps, digest\n * verification, caller-owned caching, and structured non-throwing results.\n */\nimport { createHash } from 'crypto';\nimport Ajv from 'ajv';\n// Loaded via `require` (extension-lenient CJS resolution) rather than a\n// bare-specifier `import` — ajv ships no `exports` map, so Node's ESM resolver\n// would demand an explicit `ajv/dist/2020.js`. The ESM build gets a\n// `createRequire` shim, so `require` is available in both formats.\nconst Ajv2020 = require('ajv/dist/2020') as typeof import('ajv/dist/2020').default;\nimport addFormats from 'ajv-formats';\nimport { ssrfSafeFetch, SSRF_TRANSIENT_CODES, SsrfRefusedError } from '../net/ssrf-fetch';\nimport {\n DEFAULT_MAX_KEYWORDS,\n DEFAULT_MAX_REF_COUNT,\n DEFAULT_MAX_REF_DEPTH,\n DEFAULT_VALIDATION_BUDGET_MS,\n resolveSchemaRefs,\n SchemaRefSandboxError,\n type ResolveSchemaRefsOptions,\n} from '../v2/format-schema/sandbox-refs';\nimport { findUnsafeRegexPattern, unsafeRegexDetails } from '../v2/format-schema/regex-safety';\n\nexport interface CanonicalReference {\n uri: string;\n /** `sha256:` prefix plus 64 lowercase hex characters. */\n digest: string;\n}\n\nexport type CanonicalReferenceKind = 'format_schema' | 'platform_extensions' | 'generic';\n\nexport type CanonicalReferenceStatus =\n | 'resolved'\n | 'unresolvable'\n | 'invalid_document'\n | 'invalid_schema'\n | 'digest_mismatch'\n | 'blocked_unsafe_url'\n | 'invalid_ref';\n\nexport type CanonicalReferenceErrorCode =\n | 'invalid_ref'\n | 'non_https_url'\n | 'unsafe_url'\n | 'redirect_blocked'\n | 'http_error'\n | 'network_error'\n | 'body_too_large'\n | 'invalid_json'\n | 'invalid_json_schema'\n | 'unsupported_schema_draft'\n | 'ref_sandbox_violation'\n | 'external_ref_unpinned'\n | 'keyword_limit_exceeded'\n | 'budget_exceeded'\n | 'digest_mismatch';\n\nexport interface CanonicalReferenceError {\n code: CanonicalReferenceErrorCode;\n message: string;\n /** True only for transient network/server classes callers may retry later. */\n retryable: boolean;\n /** Digest mismatch means the fetched body was not the immutable document requested. */\n securitySignal?: 'substitution_attack';\n details?: Record<string, unknown>;\n}\n\ninterface CanonicalReferenceResultBase {\n ok: boolean;\n status: CanonicalReferenceStatus;\n kind: CanonicalReferenceKind;\n ref: CanonicalReference;\n cacheKey: string;\n fromCache: boolean;\n}\n\nexport interface CanonicalReferenceResolvedResult<TDocument = unknown> extends CanonicalReferenceResultBase {\n ok: true;\n status: 'resolved';\n document: TDocument;\n body: Uint8Array;\n text: string;\n contentType?: string;\n httpStatus: number;\n schemaMeta?: {\n draft: 'draft-07' | '2020-12';\n refCount: number;\n maxRefDepthSeen: number;\n keywordCount: number;\n validationTimeMs: number;\n };\n}\n\nexport interface FormatSchemaReferenceResolvedResult extends CanonicalReferenceResolvedResult<Record<string, unknown>> {\n kind: 'format_schema';\n schemaMeta: NonNullable<CanonicalReferenceResolvedResult['schemaMeta']>;\n}\n\nexport interface CanonicalReferenceFailureResult extends CanonicalReferenceResultBase {\n ok: false;\n status: Exclude<CanonicalReferenceStatus, 'resolved'>;\n error: CanonicalReferenceError;\n httpStatus?: number;\n}\n\nexport type CanonicalReferenceResult<TDocument = unknown> =\n | CanonicalReferenceResolvedResult<TDocument>\n | CanonicalReferenceFailureResult;\n\nexport type FormatSchemaReferenceResult = FormatSchemaReferenceResolvedResult | CanonicalReferenceFailureResult;\nexport type PlatformExtensionsReferenceResult = CanonicalReferenceResult<unknown>;\n\nexport type ExternalRefDigestMap = ReadonlyMap<string, string> | Readonly<Record<string, string>>;\n\nexport interface CanonicalReferenceCache {\n get(key: string): CanonicalReferenceResolvedResult | undefined;\n set(key: string, value: CanonicalReferenceResolvedResult): void;\n}\n\nexport interface CanonicalReferenceResolverOptions {\n /** Caller-owned cache. Defaults to a fresh per-resolver Map. */\n cache?: CanonicalReferenceCache;\n /** Default 5_000 ms. */\n timeoutMs?: number;\n /** Default 1 MiB. */\n maxBodyBytes?: number;\n /** Test/dev-only escape hatch for loopback fixtures. Production callers should leave false. */\n allowUnsafeHttp?: boolean;\n /** Test/dev-only escape hatch for loopback/private-network fixtures. Production callers should leave false. */\n allowPrivateNetwork?: boolean;\n /** Default 8 for `format_schema` `$ref` walks. */\n maxRefDepth?: number;\n /** Default 256 for `format_schema` `$ref` walks. */\n maxRefCount?: number;\n /** Default 10_000 approximate schema keyword/object-key bound. */\n maxKeywords?: number;\n /** Default 250 ms soft compile-time budget for JSON Schema validation. */\n validationBudgetMs?: number;\n /** Required for each external `$ref` URI in `format_schema`; keeps transitive schemas immutable. */\n externalRefDigests?: ExternalRefDigestMap;\n /** Default 8 MiB cumulative cap across external `$ref` bodies. */\n maxTotalRefBytes?: number;\n /** Default 5_000 ms total wall-clock budget across external `$ref` resolution. */\n maxRefResolutionMs?: number;\n /** Override the trusted mirror host set for `format_schema` external `$ref`s. */\n mirrorHosts?: readonly string[];\n /** Single-host convenience override for `format_schema` external `$ref`s. */\n mirrorHost?: string;\n}\n\nexport interface CanonicalReferenceResolveOptions extends Omit<CanonicalReferenceResolverOptions, 'cache'> {\n cache?: CanonicalReferenceCache;\n kind?: CanonicalReferenceKind;\n}\n\nexport interface CanonicalReferenceResolver {\n cache: CanonicalReferenceCache;\n resolveFormatSchema(\n ref: CanonicalReference,\n options?: Omit<CanonicalReferenceResolveOptions, 'cache' | 'kind'>\n ): Promise<FormatSchemaReferenceResult>;\n resolvePlatformExtensions(\n ref: CanonicalReference,\n options?: Omit<CanonicalReferenceResolveOptions, 'cache' | 'kind'>\n ): Promise<CanonicalReferenceResult<unknown>>;\n resolve(\n ref: CanonicalReference,\n options?: Omit<CanonicalReferenceResolveOptions, 'cache'>\n ): Promise<CanonicalReferenceResult<unknown>>;\n}\n\nconst DEFAULT_TIMEOUT_MS = 5_000;\nconst DEFAULT_MAX_BODY_BYTES = 1024 * 1024;\nconst DEFAULT_MAX_TOTAL_REF_BYTES = 8 * 1024 * 1024;\nconst DIGEST_RE = /^sha256:[0-9a-f]{64}$/;\nconst DRAFT_07_URIS = new Set(['http://json-schema.org/draft-07/schema#', 'https://json-schema.org/draft-07/schema#']);\nconst DRAFT_2020_12_URIS = new Set([\n 'https://json-schema.org/draft/2020-12/schema',\n 'https://json-schema.org/draft/2020-12/schema#',\n]);\nconst SPECIAL_USE_HOSTS = new Set([\n 'localhost',\n 'example',\n 'example.com',\n 'example.net',\n 'example.org',\n 'home.arpa',\n 'invalid',\n 'local',\n 'test',\n]);\n\nexport function createCanonicalReferenceCache(): CanonicalReferenceCache {\n const store = new Map<string, CanonicalReferenceResolvedResult>();\n return {\n get: key => store.get(key),\n set: (key, value) => {\n store.set(key, value);\n },\n };\n}\n\nexport function canonicalReferenceCacheKey(\n ref: CanonicalReference,\n options: Pick<CanonicalReferenceResolveOptions, 'allowPrivateNetwork' | 'allowUnsafeHttp' | 'maxBodyBytes'> = {}\n): string {\n const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;\n const privateNetwork = options.allowPrivateNetwork === true ? 1 : 0;\n const unsafeHttp = options.allowUnsafeHttp === true ? 1 : 0;\n return `${ref.uri}@${ref.digest}#priv=${privateNetwork}#http=${unsafeHttp}#max=${maxBodyBytes}`;\n}\n\nfunction cloneResolved<TDocument>(\n result: CanonicalReferenceResolvedResult<TDocument>\n): CanonicalReferenceResolvedResult<TDocument> {\n return {\n ...result,\n ref: { ...result.ref },\n body: Uint8Array.from(result.body),\n document: structuredClone(result.document),\n schemaMeta: result.schemaMeta ? { ...result.schemaMeta } : undefined,\n };\n}\n\nexport function createCanonicalReferenceResolver(\n defaults: CanonicalReferenceResolverOptions = {}\n): CanonicalReferenceResolver {\n const cache = defaults.cache ?? createCanonicalReferenceCache();\n const merge = (options: Omit<CanonicalReferenceResolveOptions, 'cache'> = {}): CanonicalReferenceResolveOptions => ({\n ...defaults,\n ...options,\n cache,\n });\n return {\n cache,\n resolveFormatSchema: (ref, options) =>\n resolveFormatSchemaReference(ref, merge({ ...options, kind: 'format_schema' })),\n resolvePlatformExtensions: (ref, options) =>\n resolvePlatformExtensionsReference(ref, merge({ ...options, kind: 'platform_extensions' })),\n resolve: (ref, options) => resolveCanonicalReference(ref, merge(options)),\n };\n}\n\nexport async function resolvePlatformExtensionsReference(\n ref: CanonicalReference,\n options: CanonicalReferenceResolveOptions = {}\n): Promise<PlatformExtensionsReferenceResult> {\n return resolveCanonicalReference(ref, { ...options, kind: 'platform_extensions' });\n}\n\nexport async function resolveFormatSchemaReference(\n ref: CanonicalReference,\n options: CanonicalReferenceResolveOptions = {}\n): Promise<FormatSchemaReferenceResult> {\n const fetched = await fetchJsonReference(ref, { ...options, kind: 'format_schema' });\n if (!fetched.ok) return fetched;\n if (!fetched.document || typeof fetched.document !== 'object' || Array.isArray(fetched.document)) {\n return fail(\n 'format_schema',\n ref,\n fetched.cacheKey,\n 'invalid_schema',\n 'invalid_json',\n 'format_schema must be a JSON object'\n );\n }\n\n const schema = fetched.document as Record<string, unknown>;\n const validated = await validateFormatSchema(schema, ref.uri, options);\n if (!validated.ok) {\n return {\n ok: false,\n status: validated.status ?? 'invalid_schema',\n kind: 'format_schema',\n ref,\n cacheKey: fetched.cacheKey,\n fromCache: false,\n error: validated.error,\n };\n }\n\n return cloneResolved({\n ...fetched,\n kind: 'format_schema',\n document: validated.schema,\n schemaMeta: validated.meta,\n }) as FormatSchemaReferenceResolvedResult;\n}\n\nexport async function resolveCanonicalReference(\n ref: CanonicalReference,\n options: CanonicalReferenceResolveOptions = {}\n): Promise<CanonicalReferenceResult<unknown>> {\n return fetchJsonReference(ref, options);\n}\n\nasync function fetchJsonReference(\n ref: CanonicalReference,\n options: CanonicalReferenceResolveOptions\n): Promise<CanonicalReferenceResult<unknown>> {\n const kind = options.kind ?? 'generic';\n const valid = validateRef(ref, kind, options);\n if (!valid.ok) return valid.result;\n\n const cache = options.cache;\n const cacheKey = canonicalReferenceCacheKey(ref, options);\n const cached = cache?.get(cacheKey);\n if (cached) {\n return { ...cloneResolved(cached), kind, ref, cacheKey, fromCache: true };\n }\n\n let response;\n try {\n response = await ssrfSafeFetch(ref.uri, {\n method: 'GET',\n headers: { accept: 'application/json, application/schema+json' },\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n maxBodyBytes: options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES,\n allowPrivateIp: options.allowPrivateNetwork === true,\n });\n } catch (err) {\n if (err instanceof SsrfRefusedError) {\n if (err.code === 'body_exceeds_limit') {\n return fail(\n kind,\n ref,\n cacheKey,\n 'unresolvable',\n 'body_too_large',\n 'Response body exceeded the configured cap',\n {\n retryable: false,\n }\n );\n }\n if (SSRF_TRANSIENT_CODES.has(err.code)) {\n return fail(\n kind,\n ref,\n cacheKey,\n 'unresolvable',\n 'network_error',\n 'Transient network failure while fetching canonical reference',\n {\n retryable: true,\n }\n );\n }\n const blockedCode = err.code === 'non_https_without_opt_in' ? 'non_https_url' : 'unsafe_url';\n return fail(\n kind,\n ref,\n cacheKey,\n 'blocked_unsafe_url',\n blockedCode,\n 'Canonical reference URL was blocked by SSRF policy',\n {\n details: { ssrfCode: err.code, hostname: err.hostname },\n }\n );\n }\n return fail(\n kind,\n ref,\n cacheKey,\n 'unresolvable',\n 'network_error',\n 'Network failure while fetching canonical reference',\n {\n retryable: true,\n }\n );\n }\n\n if (response.status >= 300 && response.status < 400) {\n return fail(\n kind,\n ref,\n cacheKey,\n 'blocked_unsafe_url',\n 'redirect_blocked',\n 'HTTP redirects are disabled for canonical references',\n {\n httpStatus: response.status,\n }\n );\n }\n if (response.status < 200 || response.status >= 300) {\n return fail(\n kind,\n ref,\n cacheKey,\n 'unresolvable',\n 'http_error',\n `HTTP ${response.status} while fetching canonical reference`,\n {\n retryable: response.status >= 500 || response.status === 429,\n httpStatus: response.status,\n }\n );\n }\n\n const actualDigest = `sha256:${createHash('sha256').update(response.body).digest('hex')}`;\n if (actualDigest !== ref.digest) {\n return fail(kind, ref, cacheKey, 'digest_mismatch', 'digest_mismatch', 'Canonical reference digest mismatch', {\n securitySignal: 'substitution_attack',\n details: { actualDigest },\n });\n }\n\n const text = new TextDecoder('utf-8').decode(response.body);\n let document: unknown;\n try {\n document = JSON.parse(text);\n } catch {\n return fail(kind, ref, cacheKey, 'invalid_document', 'invalid_json', 'Canonical reference body is not valid JSON');\n }\n\n const result: CanonicalReferenceResolvedResult = {\n ok: true,\n status: 'resolved',\n kind,\n ref,\n cacheKey,\n fromCache: false,\n document,\n body: response.body,\n text,\n contentType: response.headers['content-type'],\n httpStatus: response.status,\n };\n const cachedResult = cloneResolved(result);\n cache?.set(cacheKey, cachedResult);\n return cloneResolved(cachedResult);\n}\n\nasync function fetchJsonReferenceDocument(\n ref: CanonicalReference,\n kind: CanonicalReferenceKind,\n options: CanonicalReferenceResolveOptions\n): Promise<CanonicalReferenceResult<unknown>> {\n return fetchJsonReference(ref, { ...options, kind });\n}\n\nfunction validateRef(\n ref: CanonicalReference,\n kind: CanonicalReferenceKind,\n options: CanonicalReferenceResolveOptions\n): { ok: true } | { ok: false; result: CanonicalReferenceFailureResult } {\n const fallbackRef: CanonicalReference = {\n uri: typeof ref?.uri === 'string' ? ref.uri : '<missing>',\n digest: typeof ref?.digest === 'string' ? ref.digest : '<missing>',\n };\n const cacheKey = canonicalReferenceCacheKey(fallbackRef, options);\n if (!ref || typeof ref.uri !== 'string' || typeof ref.digest !== 'string') {\n return {\n ok: false,\n result: fail(\n kind,\n fallbackRef,\n cacheKey,\n 'invalid_ref',\n 'invalid_ref',\n 'Canonical reference must carry { uri, digest }'\n ),\n };\n }\n if (!DIGEST_RE.test(ref.digest)) {\n return {\n ok: false,\n result: fail(\n kind,\n ref,\n cacheKey,\n 'invalid_ref',\n 'invalid_ref',\n 'Canonical reference digest must be `sha256:` plus 64 lowercase hex characters'\n ),\n };\n }\n let parsed: URL;\n try {\n parsed = new URL(ref.uri);\n } catch {\n return {\n ok: false,\n result: fail(kind, ref, cacheKey, 'invalid_ref', 'invalid_ref', 'Canonical reference URI is not a valid URL'),\n };\n }\n const specialUseHost = specialUseHostname(parsed.hostname);\n if (specialUseHost) {\n return {\n ok: false,\n result: fail(\n kind,\n ref,\n cacheKey,\n 'blocked_unsafe_url',\n 'unsafe_url',\n 'Canonical reference URI uses a special-use hostname',\n { details: { hostname: specialUseHost } }\n ),\n };\n }\n if (parsed.protocol !== 'https:') {\n if (parsed.protocol === 'http:' && options.allowUnsafeHttp === true) return { ok: true };\n return {\n ok: false,\n result: fail(\n kind,\n ref,\n cacheKey,\n 'blocked_unsafe_url',\n 'non_https_url',\n 'Canonical reference URI must use https://'\n ),\n };\n }\n return { ok: true };\n}\n\nfunction specialUseHostname(hostname: string): string | null {\n const host = hostname\n .replace(/^\\[|\\]$/g, '')\n .toLowerCase()\n .replace(/\\.$/, '');\n if (SPECIAL_USE_HOSTS.has(host)) return host;\n if (host.endsWith('.example')) return host;\n if (host.endsWith('.home.arpa')) return host;\n if (host.endsWith('.localhost')) return host;\n if (host.endsWith('.local')) return host;\n if (host.endsWith('.invalid')) return host;\n if (host.endsWith('.test')) return host;\n if (host.endsWith('.example.com')) return host;\n if (host.endsWith('.example.net')) return host;\n if (host.endsWith('.example.org')) return host;\n return null;\n}\n\nfunction fail(\n kind: CanonicalReferenceKind,\n ref: CanonicalReference,\n cacheKey: string,\n status: Exclude<CanonicalReferenceStatus, 'resolved'>,\n code: CanonicalReferenceErrorCode,\n message: string,\n options: {\n retryable?: boolean;\n securitySignal?: 'substitution_attack';\n details?: Record<string, unknown>;\n httpStatus?: number;\n } = {}\n): CanonicalReferenceFailureResult {\n return {\n ok: false,\n status,\n kind,\n ref,\n cacheKey,\n fromCache: false,\n httpStatus: options.httpStatus,\n error: {\n code,\n message,\n retryable: options.retryable ?? false,\n securitySignal: options.securitySignal,\n details: options.details,\n },\n };\n}\n\ntype FormatSchemaValidation =\n | {\n ok: true;\n schema: Record<string, unknown>;\n meta: NonNullable<CanonicalReferenceResolvedResult['schemaMeta']>;\n }\n | { ok: false; status?: Exclude<CanonicalReferenceStatus, 'resolved'>; error: CanonicalReferenceError };\n\nasync function validateFormatSchema(\n schema: Record<string, unknown>,\n parentUri: string,\n options: CanonicalReferenceResolveOptions\n): Promise<FormatSchemaValidation> {\n const draft = detectDraft(schema);\n if (!draft.ok) return { ok: false, error: draft.error };\n\n let resolved;\n try {\n resolved = await resolveSchemaRefs(schema, parentUri, {\n maxDepth: options.maxRefDepth ?? DEFAULT_MAX_REF_DEPTH,\n maxRefCount: options.maxRefCount ?? DEFAULT_MAX_REF_COUNT,\n maxBodyBytes: options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n mirrorHost: options.mirrorHost,\n mirrorHosts: options.mirrorHosts,\n fetchExternal: makeExternalSchemaFetcher(options),\n } satisfies ResolveSchemaRefsOptions);\n } catch (err) {\n if (err instanceof SchemaRefSandboxError) {\n const mapped = canonicalFailureFromSchemaRefError(err);\n if (mapped) {\n return {\n ok: false,\n status: mapped.status,\n error: mapped.error,\n };\n }\n return {\n ok: false,\n status: 'invalid_schema',\n error: {\n code: 'ref_sandbox_violation',\n message: 'format_schema $ref sandbox rejected a reference',\n retryable: false,\n details: { sandboxCode: err.code, ref: err.ref },\n },\n };\n }\n return {\n ok: false,\n status: 'invalid_schema',\n error: { code: 'invalid_json_schema', message: 'format_schema $ref resolution failed', retryable: false },\n };\n }\n\n const keywordCount = countSchemaKeywords(resolved.schema);\n const maxKeywords = options.maxKeywords ?? DEFAULT_MAX_KEYWORDS;\n if (keywordCount > maxKeywords) {\n return {\n ok: false,\n error: {\n code: 'keyword_limit_exceeded',\n message: `format_schema keyword count exceeded ${maxKeywords}`,\n retryable: false,\n details: { keywordCount, maxKeywords },\n },\n };\n }\n\n const unsafeRegex = findUnsafeRegexPattern(resolved.schema);\n if (unsafeRegex) {\n return {\n ok: false,\n error: {\n code: 'budget_exceeded',\n message: 'format_schema regex safety budget exceeded',\n retryable: false,\n details: unsafeRegexDetails(unsafeRegex),\n },\n };\n }\n\n const ajv = draft.draft === '2020-12' ? getDraft2020Ajv() : getDraft07Ajv();\n const started = process.cpuUsage();\n try {\n ajv.compile(resolved.schema);\n } catch (err) {\n return {\n ok: false,\n error: {\n code: 'invalid_json_schema',\n message: 'format_schema is not a valid JSON Schema document',\n retryable: false,\n details: { reason: err instanceof Error ? err.message : String(err) },\n },\n };\n }\n // Ajv compilation is synchronous; CPU time avoids false budget failures when\n // the process is descheduled during highly parallel test or CI runs.\n const validationTimeMs = cpuUsageMs(started);\n const validationBudgetMs = options.validationBudgetMs ?? DEFAULT_VALIDATION_BUDGET_MS;\n if (validationTimeMs > validationBudgetMs) {\n return {\n ok: false,\n error: {\n code: 'invalid_json_schema',\n message: `format_schema compile exceeded ${validationBudgetMs} ms validation budget`,\n retryable: false,\n details: { validationTimeMs, validationBudgetMs },\n },\n };\n }\n\n return {\n ok: true,\n schema: resolved.schema,\n meta: {\n draft: draft.draft,\n refCount: resolved.refCount,\n maxRefDepthSeen: resolved.maxDepthSeen,\n keywordCount,\n validationTimeMs,\n },\n };\n}\n\nfunction cpuUsageMs(started: NodeJS.CpuUsage): number {\n const elapsed = process.cpuUsage(started);\n return (elapsed.user + elapsed.system) / 1000;\n}\n\nfunction detectDraft(\n schema: Record<string, unknown>\n): { ok: true; draft: 'draft-07' | '2020-12' } | { ok: false; error: CanonicalReferenceError } {\n const raw = schema.$schema;\n if (raw === undefined) {\n return {\n ok: false,\n error: {\n code: 'unsupported_schema_draft',\n message: 'format_schema must declare $schema',\n retryable: false,\n },\n };\n }\n if (typeof raw !== 'string') {\n return {\n ok: false,\n error: {\n code: 'unsupported_schema_draft',\n message: 'format_schema.$schema must be a JSON Schema draft URI string',\n retryable: false,\n },\n };\n }\n if (DRAFT_07_URIS.has(raw)) return { ok: true, draft: 'draft-07' };\n if (DRAFT_2020_12_URIS.has(raw)) return { ok: true, draft: '2020-12' };\n return {\n ok: false,\n error: {\n code: 'unsupported_schema_draft',\n message: 'format_schema must declare Draft-07 or Draft 2020-12',\n retryable: false,\n details: { schema: raw },\n },\n };\n}\n\nfunction getDraft07Ajv(): Ajv {\n const ajv = new Ajv({\n strict: false,\n allErrors: true,\n validateSchema: true,\n validateFormats: true,\n addUsedSchema: false,\n });\n addFormats(ajv);\n return ajv;\n}\n\nfunction getDraft2020Ajv(): InstanceType<typeof Ajv2020> {\n const ajv = new Ajv2020({\n strict: false,\n allErrors: true,\n validateSchema: true,\n validateFormats: true,\n addUsedSchema: false,\n });\n addFormats(ajv);\n return ajv;\n}\n\ntype MappedSchemaRefFailure = {\n status: Exclude<CanonicalReferenceStatus, 'resolved'>;\n error: CanonicalReferenceError;\n};\n\nfunction canonicalFailureFromSchemaRefError(err: SchemaRefSandboxError): MappedSchemaRefFailure | null {\n const details = err.details as\n | {\n canonicalStatus?: Exclude<CanonicalReferenceStatus, 'resolved'>;\n canonicalErrorCode?: CanonicalReferenceErrorCode;\n retryable?: boolean;\n securitySignal?: 'substitution_attack';\n details?: Record<string, unknown>;\n }\n | undefined;\n if (!details?.canonicalStatus || !details.canonicalErrorCode) return null;\n return {\n status: details.canonicalStatus,\n error: {\n code: details.canonicalErrorCode,\n message: err.message,\n retryable: details.retryable === true,\n securitySignal: details.securitySignal,\n details: { ref: err.ref, ...details.details },\n },\n };\n}\n\nfunction makeExternalSchemaFetcher(\n options: CanonicalReferenceResolveOptions\n): (uri: string) => Promise<Record<string, unknown>> {\n const deadlineMs = Date.now() + (options.maxRefResolutionMs ?? DEFAULT_TIMEOUT_MS);\n const maxTotalRefBytes = options.maxTotalRefBytes ?? DEFAULT_MAX_TOTAL_REF_BYTES;\n let totalRefBytes = 0;\n\n return async uri => {\n const expectedDigest = lookupExternalRefDigest(options.externalRefDigests, uri);\n if (!expectedDigest) {\n throwExternalRefFailure(uri, 'invalid_schema', 'external_ref_unpinned', 'External $ref missing pinned digest');\n }\n const refValidation = validateRef({ uri, digest: expectedDigest }, 'format_schema', options);\n if (!refValidation.ok) {\n throwExternalRefFailure(\n uri,\n refValidation.result.status,\n refValidation.result.error.code,\n refValidation.result.error.message,\n {\n retryable: refValidation.result.error.retryable,\n securitySignal: refValidation.result.error.securitySignal,\n details: refValidation.result.error.details,\n }\n );\n }\n const remainingMs = deadlineMs - Date.now();\n if (remainingMs <= 0) {\n throwExternalRefFailure(uri, 'unresolvable', 'network_error', 'External $ref resolution budget exceeded', {\n retryable: true,\n });\n }\n\n const fetched = await fetchJsonReferenceDocument({ uri, digest: expectedDigest }, 'format_schema', {\n ...options,\n timeoutMs: Math.min(options.timeoutMs ?? DEFAULT_TIMEOUT_MS, remainingMs),\n });\n if (!fetched.ok) {\n throwExternalRefFailure(\n uri,\n fetched.status,\n fetched.error.code,\n `External $ref fetch failed: ${fetched.error.message}`,\n {\n retryable: fetched.error.retryable,\n securitySignal: fetched.error.securitySignal,\n details: {\n ...fetched.error.details,\n ...(fetched.httpStatus === undefined ? {} : { httpStatus: fetched.httpStatus }),\n },\n }\n );\n }\n totalRefBytes += fetched.body.byteLength;\n if (totalRefBytes > maxTotalRefBytes) {\n throwExternalRefFailure(uri, 'unresolvable', 'body_too_large', 'External $ref total body budget exceeded', {\n details: { totalRefBytes, maxTotalRefBytes },\n });\n }\n if (!fetched.document || typeof fetched.document !== 'object' || Array.isArray(fetched.document)) {\n throwExternalRefFailure(uri, 'invalid_schema', 'invalid_json', 'External $ref body is not a JSON object');\n }\n return fetched.document as Record<string, unknown>;\n };\n}\n\nfunction lookupExternalRefDigest(digests: ExternalRefDigestMap | undefined, uri: string): string | undefined {\n if (!digests) return undefined;\n if (typeof (digests as ReadonlyMap<string, string>).get === 'function') {\n return (digests as ReadonlyMap<string, string>).get(uri);\n }\n return (digests as Readonly<Record<string, string>>)[uri];\n}\n\nfunction throwExternalRefFailure(\n uri: string,\n status: Exclude<CanonicalReferenceStatus, 'resolved'>,\n code: CanonicalReferenceErrorCode,\n message: string,\n options: {\n retryable?: boolean;\n securitySignal?: 'substitution_attack';\n details?: Record<string, unknown>;\n } = {}\n): never {\n throw new SchemaRefSandboxError('fetch_failed', message, {\n ref: uri,\n details: {\n canonicalStatus: status,\n canonicalErrorCode: code,\n retryable: options.retryable === true,\n securitySignal: options.securitySignal,\n details: options.details,\n },\n });\n}\n\nfunction countSchemaKeywords(root: unknown): number {\n const seen = new Set<unknown>();\n const walk = (node: unknown): number => {\n if (!node || typeof node !== 'object') return 0;\n if (seen.has(node)) return 0;\n seen.add(node);\n if (Array.isArray(node)) return node.reduce((sum, item) => sum + walk(item), 0);\n const obj = node as Record<string, unknown>;\n return Object.entries(obj).reduce((sum, [, value]) => sum + 1 + walk(value), 0);\n };\n return walk(root);\n}\n"],"mappings":";;;;;;AAUA,SAAS,kBAAkB;AAC3B,OAAO,SAAS;AAKhB,MAAM,UAAU,QAAQ,eAAe;AACvC,OAAO,gBAAgB;AACvB,SAAS,eAAe,sBAAsB,wBAAwB;AACtE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,wBAAwB,0BAA0B;AAsJ3D,MAAM,qBAAqB;AAC3B,MAAM,yBAAyB,OAAO;AACtC,MAAM,8BAA8B,IAAI,OAAO;AAC/C,MAAM,YAAY;AAClB,MAAM,gBAAgB,oBAAI,IAAI,CAAC,2CAA2C,0CAA0C,CAAC;AACrH,MAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EACA;AACF,CAAC;AACD,MAAM,oBAAoB,oBAAI,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,gCAAyD;AACvE,QAAM,QAAQ,oBAAI,IAA8C;AAChE,SAAO;AAAA,IACL,KAAK,SAAO,MAAM,IAAI,GAAG;AAAA,IACzB,KAAK,CAAC,KAAK,UAAU;AACnB,YAAM,IAAI,KAAK,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAEO,SAAS,2BACd,KACA,UAA8G,CAAC,GACvG;AACR,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,iBAAiB,QAAQ,wBAAwB,OAAO,IAAI;AAClE,QAAM,aAAa,QAAQ,oBAAoB,OAAO,IAAI;AAC1D,SAAO,GAAG,IAAI,GAAG,IAAI,IAAI,MAAM,SAAS,cAAc,SAAS,UAAU,QAAQ,YAAY;AAC/F;AAEA,SAAS,cACP,QAC6C;AAC7C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK,EAAE,GAAG,OAAO,IAAI;AAAA,IACrB,MAAM,WAAW,KAAK,OAAO,IAAI;AAAA,IACjC,UAAU,gBAAgB,OAAO,QAAQ;AAAA,IACzC,YAAY,OAAO,aAAa,EAAE,GAAG,OAAO,WAAW,IAAI;AAAA,EAC7D;AACF;AAEO,SAAS,iCACd,WAA8C,CAAC,GACnB;AAC5B,QAAM,QAAQ,SAAS,SAAS,8BAA8B;AAC9D,QAAM,QAAQ,CAAC,UAA2D,CAAC,OAAyC;AAAA,IAClH,GAAG;AAAA,IACH,GAAG;AAAA,IACH;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,qBAAqB,CAAC,KAAK,YACzB,6BAA6B,KAAK,MAAM,EAAE,GAAG,SAAS,MAAM,gBAAgB,CAAC,CAAC;AAAA,IAChF,2BAA2B,CAAC,KAAK,YAC/B,mCAAmC,KAAK,MAAM,EAAE,GAAG,SAAS,MAAM,sBAAsB,CAAC,CAAC;AAAA,IAC5F,SAAS,CAAC,KAAK,YAAY,0BAA0B,KAAK,MAAM,OAAO,CAAC;AAAA,EAC1E;AACF;AAEA,eAAsB,mCACpB,KACA,UAA4C,CAAC,GACD;AAC5C,SAAO,0BAA0B,KAAK,EAAE,GAAG,SAAS,MAAM,sBAAsB,CAAC;AACnF;AAEA,eAAsB,6BACpB,KACA,UAA4C,CAAC,GACP;AACtC,QAAM,UAAU,MAAM,mBAAmB,KAAK,EAAE,GAAG,SAAS,MAAM,gBAAgB,CAAC;AACnF,MAAI,CAAC,QAAQ,GAAI,QAAO;AACxB,MAAI,CAAC,QAAQ,YAAY,OAAO,QAAQ,aAAa,YAAY,MAAM,QAAQ,QAAQ,QAAQ,GAAG;AAChG,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ;AACvB,QAAM,YAAY,MAAM,qBAAqB,QAAQ,IAAI,KAAK,OAAO;AACrE,MAAI,CAAC,UAAU,IAAI;AACjB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ,UAAU,UAAU;AAAA,MAC5B,MAAM;AAAA,MACN;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB,WAAW;AAAA,MACX,OAAO,UAAU;AAAA,IACnB;AAAA,EACF;AAEA,SAAO,cAAc;AAAA,IACnB,GAAG;AAAA,IACH,MAAM;AAAA,IACN,UAAU,UAAU;AAAA,IACpB,YAAY,UAAU;AAAA,EACxB,CAAC;AACH;AAEA,eAAsB,0BACpB,KACA,UAA4C,CAAC,GACD;AAC5C,SAAO,mBAAmB,KAAK,OAAO;AACxC;AAEA,eAAe,mBACb,KACA,SAC4C;AAC5C,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,QAAQ,YAAY,KAAK,MAAM,OAAO;AAC5C,MAAI,CAAC,MAAM,GAAI,QAAO,MAAM;AAE5B,QAAM,QAAQ,QAAQ;AACtB,QAAM,WAAW,2BAA2B,KAAK,OAAO;AACxD,QAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,MAAI,QAAQ;AACV,WAAO,EAAE,GAAG,cAAc,MAAM,GAAG,MAAM,KAAK,UAAU,WAAW,KAAK;AAAA,EAC1E;AAEA,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,cAAc,IAAI,KAAK;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS,EAAE,QAAQ,4CAA4C;AAAA,MAC/D,WAAW,QAAQ,aAAa;AAAA,MAChC,cAAc,QAAQ,gBAAgB;AAAA,MACtC,gBAAgB,QAAQ,wBAAwB;AAAA,IAClD,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,QAAI,eAAe,kBAAkB;AACnC,UAAI,IAAI,SAAS,sBAAsB;AACrC,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,YACE,WAAW;AAAA,UACb;AAAA,QACF;AAAA,MACF;AACA,UAAI,qBAAqB,IAAI,IAAI,IAAI,GAAG;AACtC,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,YACE,WAAW;AAAA,UACb;AAAA,QACF;AAAA,MACF;AACA,YAAM,cAAc,IAAI,SAAS,6BAA6B,kBAAkB;AAChF,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,UACE,SAAS,EAAE,UAAU,IAAI,MAAM,UAAU,IAAI,SAAS;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,UAAU,OAAO,SAAS,SAAS,KAAK;AACnD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE,YAAY,SAAS;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,SAAS,OAAO,SAAS,UAAU,KAAK;AACnD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,SAAS,MAAM;AAAA,MACvB;AAAA,QACE,WAAW,SAAS,UAAU,OAAO,SAAS,WAAW;AAAA,QACzD,YAAY,SAAS;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,UAAU,WAAW,QAAQ,EAAE,OAAO,SAAS,IAAI,EAAE,OAAO,KAAK,CAAC;AACvF,MAAI,iBAAiB,IAAI,QAAQ;AAC/B,WAAO,KAAK,MAAM,KAAK,UAAU,mBAAmB,mBAAmB,uCAAuC;AAAA,MAC5G,gBAAgB;AAAA,MAChB,SAAS,EAAE,aAAa;AAAA,IAC1B,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,IAAI,YAAY,OAAO,EAAE,OAAO,SAAS,IAAI;AAC1D,MAAI;AACJ,MAAI;AACF,eAAW,KAAK,MAAM,IAAI;AAAA,EAC5B,QAAQ;AACN,WAAO,KAAK,MAAM,KAAK,UAAU,oBAAoB,gBAAgB,4CAA4C;AAAA,EACnH;AAEA,QAAM,SAA2C;AAAA,IAC/C,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,MAAM,SAAS;AAAA,IACf;AAAA,IACA,aAAa,SAAS,QAAQ,cAAc;AAAA,IAC5C,YAAY,SAAS;AAAA,EACvB;AACA,QAAM,eAAe,cAAc,MAAM;AACzC,SAAO,IAAI,UAAU,YAAY;AACjC,SAAO,cAAc,YAAY;AACnC;AAEA,eAAe,2BACb,KACA,MACA,SAC4C;AAC5C,SAAO,mBAAmB,KAAK,EAAE,GAAG,SAAS,KAAK,CAAC;AACrD;AAEA,SAAS,YACP,KACA,MACA,SACuE;AACvE,QAAM,cAAkC;AAAA,IACtC,KAAK,OAAO,KAAK,QAAQ,WAAW,IAAI,MAAM;AAAA,IAC9C,QAAQ,OAAO,KAAK,WAAW,WAAW,IAAI,SAAS;AAAA,EACzD;AACA,QAAM,WAAW,2BAA2B,aAAa,OAAO;AAChE,MAAI,CAAC,OAAO,OAAO,IAAI,QAAQ,YAAY,OAAO,IAAI,WAAW,UAAU;AACzE,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,UAAU,KAAK,IAAI,MAAM,GAAG;AAC/B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI;AACJ,MAAI;AACF,aAAS,IAAI,IAAI,IAAI,GAAG;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ,KAAK,MAAM,KAAK,UAAU,eAAe,eAAe,4CAA4C;AAAA,IAC9G;AAAA,EACF;AACA,QAAM,iBAAiB,mBAAmB,OAAO,QAAQ;AACzD,MAAI,gBAAgB;AAClB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,EAAE,SAAS,EAAE,UAAU,eAAe,EAAE;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,aAAa,UAAU;AAChC,QAAI,OAAO,aAAa,WAAW,QAAQ,oBAAoB,KAAM,QAAO,EAAE,IAAI,KAAK;AACvF,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,IAAI,KAAK;AACpB;AAEA,SAAS,mBAAmB,UAAiC;AAC3D,QAAM,OAAO,SACV,QAAQ,YAAY,EAAE,EACtB,YAAY,EACZ,QAAQ,OAAO,EAAE;AACpB,MAAI,kBAAkB,IAAI,IAAI,EAAG,QAAO;AACxC,MAAI,KAAK,SAAS,UAAU,EAAG,QAAO;AACtC,MAAI,KAAK,SAAS,YAAY,EAAG,QAAO;AACxC,MAAI,KAAK,SAAS,YAAY,EAAG,QAAO;AACxC,MAAI,KAAK,SAAS,QAAQ,EAAG,QAAO;AACpC,MAAI,KAAK,SAAS,UAAU,EAAG,QAAO;AACtC,MAAI,KAAK,SAAS,OAAO,EAAG,QAAO;AACnC,MAAI,KAAK,SAAS,cAAc,EAAG,QAAO;AAC1C,MAAI,KAAK,SAAS,cAAc,EAAG,QAAO;AAC1C,MAAI,KAAK,SAAS,cAAc,EAAG,QAAO;AAC1C,SAAO;AACT;AAEA,SAAS,KACP,MACA,KACA,UACA,QACA,MACA,SACA,UAKI,CAAC,GAC4B;AACjC,SAAO;AAAA,IACL,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,YAAY,QAAQ;AAAA,IACpB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,WAAW,QAAQ,aAAa;AAAA,MAChC,gBAAgB,QAAQ;AAAA,MACxB,SAAS,QAAQ;AAAA,IACnB;AAAA,EACF;AACF;AAUA,eAAe,qBACb,QACA,WACA,SACiC;AACjC,QAAM,QAAQ,YAAY,MAAM;AAChC,MAAI,CAAC,MAAM,GAAI,QAAO,EAAE,IAAI,OAAO,OAAO,MAAM,MAAM;AAEtD,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,kBAAkB,QAAQ,WAAW;AAAA,MACpD,UAAU,QAAQ,eAAe;AAAA,MACjC,aAAa,QAAQ,eAAe;AAAA,MACpC,cAAc,QAAQ,gBAAgB;AAAA,MACtC,WAAW,QAAQ,aAAa;AAAA,MAChC,YAAY,QAAQ;AAAA,MACpB,aAAa,QAAQ;AAAA,MACrB,eAAe,0BAA0B,OAAO;AAAA,IAClD,CAAoC;AAAA,EACtC,SAAS,KAAK;AACZ,QAAI,eAAe,uBAAuB;AACxC,YAAM,SAAS,mCAAmC,GAAG;AACrD,UAAI,QAAQ;AACV,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,QAAQ,OAAO;AAAA,UACf,OAAO,OAAO;AAAA,QAChB;AAAA,MACF;AACA,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,SAAS,EAAE,aAAa,IAAI,MAAM,KAAK,IAAI,IAAI;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,OAAO,EAAE,MAAM,uBAAuB,SAAS,wCAAwC,WAAW,MAAM;AAAA,IAC1G;AAAA,EACF;AAEA,QAAM,eAAe,oBAAoB,SAAS,MAAM;AACxD,QAAM,cAAc,QAAQ,eAAe;AAC3C,MAAI,eAAe,aAAa;AAC9B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,wCAAwC,WAAW;AAAA,QAC5D,WAAW;AAAA,QACX,SAAS,EAAE,cAAc,YAAY;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,uBAAuB,SAAS,MAAM;AAC1D,MAAI,aAAa;AACf,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,WAAW;AAAA,QACX,SAAS,mBAAmB,WAAW;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,MAAM,UAAU,YAAY,gBAAgB,IAAI,cAAc;AAC1E,QAAM,UAAU,QAAQ,SAAS;AACjC,MAAI;AACF,QAAI,QAAQ,SAAS,MAAM;AAAA,EAC7B,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,WAAW;AAAA,QACX,SAAS,EAAE,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AAGA,QAAM,mBAAmB,WAAW,OAAO;AAC3C,QAAM,qBAAqB,QAAQ,sBAAsB;AACzD,MAAI,mBAAmB,oBAAoB;AACzC,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,kCAAkC,kBAAkB;AAAA,QAC7D,WAAW;AAAA,QACX,SAAS,EAAE,kBAAkB,mBAAmB;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ,SAAS;AAAA,IACjB,MAAM;AAAA,MACJ,OAAO,MAAM;AAAA,MACb,UAAU,SAAS;AAAA,MACnB,iBAAiB,SAAS;AAAA,MAC1B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WAAW,SAAkC;AACpD,QAAM,UAAU,QAAQ,SAAS,OAAO;AACxC,UAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C;AAEA,SAAS,YACP,QAC6F;AAC7F,QAAM,MAAM,OAAO;AACnB,MAAI,QAAQ,QAAW;AACrB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,MAAI,cAAc,IAAI,GAAG,EAAG,QAAO,EAAE,IAAI,MAAM,OAAO,WAAW;AACjE,MAAI,mBAAmB,IAAI,GAAG,EAAG,QAAO,EAAE,IAAI,MAAM,OAAO,UAAU;AACrE,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,MACX,SAAS,EAAE,QAAQ,IAAI;AAAA,IACzB;AAAA,EACF;AACF;AAEA,SAAS,gBAAqB;AAC5B,QAAM,MAAM,IAAI,IAAI;AAAA,IAClB,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB,CAAC;AACD,aAAW,GAAG;AACd,SAAO;AACT;AAEA,SAAS,kBAAgD;AACvD,QAAM,MAAM,IAAI,QAAQ;AAAA,IACtB,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB,CAAC;AACD,aAAW,GAAG;AACd,SAAO;AACT;AAOA,SAAS,mCAAmC,KAA2D;AACrG,QAAM,UAAU,IAAI;AASpB,MAAI,CAAC,SAAS,mBAAmB,CAAC,QAAQ,mBAAoB,QAAO;AACrE,SAAO;AAAA,IACL,QAAQ,QAAQ;AAAA,IAChB,OAAO;AAAA,MACL,MAAM,QAAQ;AAAA,MACd,SAAS,IAAI;AAAA,MACb,WAAW,QAAQ,cAAc;AAAA,MACjC,gBAAgB,QAAQ;AAAA,MACxB,SAAS,EAAE,KAAK,IAAI,KAAK,GAAG,QAAQ,QAAQ;AAAA,IAC9C;AAAA,EACF;AACF;AAEA,SAAS,0BACP,SACmD;AACnD,QAAM,aAAa,KAAK,IAAI,KAAK,QAAQ,sBAAsB;AAC/D,QAAM,mBAAmB,QAAQ,oBAAoB;AACrD,MAAI,gBAAgB;AAEpB,SAAO,OAAM,QAAO;AAClB,UAAM,iBAAiB,wBAAwB,QAAQ,oBAAoB,GAAG;AAC9E,QAAI,CAAC,gBAAgB;AACnB,8BAAwB,KAAK,kBAAkB,yBAAyB,qCAAqC;AAAA,IAC/G;AACA,UAAM,gBAAgB,YAAY,EAAE,KAAK,QAAQ,eAAe,GAAG,iBAAiB,OAAO;AAC3F,QAAI,CAAC,cAAc,IAAI;AACrB;AAAA,QACE;AAAA,QACA,cAAc,OAAO;AAAA,QACrB,cAAc,OAAO,MAAM;AAAA,QAC3B,cAAc,OAAO,MAAM;AAAA,QAC3B;AAAA,UACE,WAAW,cAAc,OAAO,MAAM;AAAA,UACtC,gBAAgB,cAAc,OAAO,MAAM;AAAA,UAC3C,SAAS,cAAc,OAAO,MAAM;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AACA,UAAM,cAAc,aAAa,KAAK,IAAI;AAC1C,QAAI,eAAe,GAAG;AACpB,8BAAwB,KAAK,gBAAgB,iBAAiB,4CAA4C;AAAA,QACxG,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,UAAM,UAAU,MAAM,2BAA2B,EAAE,KAAK,QAAQ,eAAe,GAAG,iBAAiB;AAAA,MACjG,GAAG;AAAA,MACH,WAAW,KAAK,IAAI,QAAQ,aAAa,oBAAoB,WAAW;AAAA,IAC1E,CAAC;AACD,QAAI,CAAC,QAAQ,IAAI;AACf;AAAA,QACE;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ,MAAM;AAAA,QACd,+BAA+B,QAAQ,MAAM,OAAO;AAAA,QACpD;AAAA,UACE,WAAW,QAAQ,MAAM;AAAA,UACzB,gBAAgB,QAAQ,MAAM;AAAA,UAC9B,SAAS;AAAA,YACP,GAAG,QAAQ,MAAM;AAAA,YACjB,GAAI,QAAQ,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,WAAW;AAAA,UAC/E;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,qBAAiB,QAAQ,KAAK;AAC9B,QAAI,gBAAgB,kBAAkB;AACpC,8BAAwB,KAAK,gBAAgB,kBAAkB,4CAA4C;AAAA,QACzG,SAAS,EAAE,eAAe,iBAAiB;AAAA,MAC7C,CAAC;AAAA,IACH;AACA,QAAI,CAAC,QAAQ,YAAY,OAAO,QAAQ,aAAa,YAAY,MAAM,QAAQ,QAAQ,QAAQ,GAAG;AAChG,8BAAwB,KAAK,kBAAkB,gBAAgB,yCAAyC;AAAA,IAC1G;AACA,WAAO,QAAQ;AAAA,EACjB;AACF;AAEA,SAAS,wBAAwB,SAA2C,KAAiC;AAC3G,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,OAAQ,QAAwC,QAAQ,YAAY;AACtE,WAAQ,QAAwC,IAAI,GAAG;AAAA,EACzD;AACA,SAAQ,QAA6C,GAAG;AAC1D;AAEA,SAAS,wBACP,KACA,QACA,MACA,SACA,UAII,CAAC,GACE;AACP,QAAM,IAAI,sBAAsB,gBAAgB,SAAS;AAAA,IACvD,KAAK;AAAA,IACL,SAAS;AAAA,MACP,iBAAiB;AAAA,MACjB,oBAAoB;AAAA,MACpB,WAAW,QAAQ,cAAc;AAAA,MACjC,gBAAgB,QAAQ;AAAA,MACxB,SAAS,QAAQ;AAAA,IACnB;AAAA,EACF,CAAC;AACH;AAEA,SAAS,oBAAoB,MAAuB;AAClD,QAAM,OAAO,oBAAI,IAAa;AAC9B,QAAM,OAAO,CAAC,SAA0B;AACtC,QAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAI,KAAK,IAAI,IAAI,EAAG,QAAO;AAC3B,SAAK,IAAI,IAAI;AACb,QAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,IAAI,GAAG,CAAC;AAC9E,UAAM,MAAM;AACZ,WAAO,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,MAAM,MAAM,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,EAChF;AACA,SAAO,KAAK,IAAI;AAClB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/canonical-references/index.ts"],"sourcesContent":["import { fileURLToPath as __adcpFileURLToPath } from 'node:url';\nimport { dirname as __adcpDirname } from 'node:path';\nimport { createRequire as __adcpCreateRequire } from 'node:module';\nconst __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));\nconst require = __adcpCreateRequire(import.meta.url);\n/**\n * Hardened resolver for immutable AdCP canonical references.\n *\n * `format_schema` and `platform_extensions` share the same reference shape:\n * `{ uri, digest }`, where digest is `sha256:` plus a 64-character lowercase\n * hex digest of the fetched body. This module gives callers one security\n * boundary for resolving those references: HTTPS-only by default, DNS-pinned\n * SSRF-safe fetches, redirects disabled, body and timeout caps, digest\n * verification, caller-owned caching, and structured non-throwing results.\n */\nimport { createHash } from 'crypto';\nimport Ajv from 'ajv';\n// Loaded via `require` (extension-lenient CJS resolution) rather than a\n// bare-specifier `import` — ajv ships no `exports` map, so Node's ESM resolver\n// would demand an explicit `ajv/dist/2020.js`. The ESM build gets a\n// `createRequire` shim, so `require` is available in both formats.\nconst Ajv2020 = require('ajv/dist/2020') as typeof import('ajv/dist/2020').default;\nimport addFormats from 'ajv-formats';\nimport { ssrfSafeFetch, SSRF_TRANSIENT_CODES, SsrfRefusedError } from '../net/ssrf-fetch';\nimport {\n DEFAULT_MAX_KEYWORDS,\n DEFAULT_MAX_REF_COUNT,\n DEFAULT_MAX_REF_DEPTH,\n DEFAULT_VALIDATION_BUDGET_MS,\n resolveSchemaRefs,\n SchemaRefSandboxError,\n type ResolveSchemaRefsOptions,\n} from '../v2/format-schema/sandbox-refs';\nimport { findUnsafeRegexPattern, unsafeRegexDetails } from '../v2/format-schema/regex-safety';\n\nexport interface CanonicalReference {\n uri: string;\n /** `sha256:` prefix plus 64 lowercase hex characters. */\n digest: string;\n}\n\nexport type CanonicalReferenceKind = 'format_schema' | 'platform_extensions' | 'generic';\n\nexport type CanonicalReferenceStatus =\n | 'resolved'\n | 'unresolvable'\n | 'invalid_document'\n | 'invalid_schema'\n | 'digest_mismatch'\n | 'blocked_unsafe_url'\n | 'invalid_ref';\n\nexport type CanonicalReferenceErrorCode =\n | 'invalid_ref'\n | 'non_https_url'\n | 'unsafe_url'\n | 'redirect_blocked'\n | 'http_error'\n | 'network_error'\n | 'body_too_large'\n | 'invalid_json'\n | 'invalid_json_schema'\n | 'unsupported_schema_draft'\n | 'ref_sandbox_violation'\n | 'external_ref_unpinned'\n | 'keyword_limit_exceeded'\n | 'budget_exceeded'\n | 'digest_mismatch';\n\nexport interface CanonicalReferenceError {\n code: CanonicalReferenceErrorCode;\n message: string;\n /** True only for transient network/server classes callers may retry later. */\n retryable: boolean;\n /** Digest mismatch means the fetched body was not the immutable document requested. */\n securitySignal?: 'substitution_attack';\n details?: Record<string, unknown>;\n}\n\ninterface CanonicalReferenceResultBase {\n ok: boolean;\n status: CanonicalReferenceStatus;\n kind: CanonicalReferenceKind;\n ref: CanonicalReference;\n cacheKey: string;\n fromCache: boolean;\n}\n\nexport interface CanonicalReferenceResolvedResult<TDocument = unknown> extends CanonicalReferenceResultBase {\n ok: true;\n status: 'resolved';\n document: TDocument;\n body: Uint8Array;\n text: string;\n contentType?: string;\n httpStatus: number;\n schemaMeta?: {\n draft: 'draft-07' | '2020-12';\n refCount: number;\n maxRefDepthSeen: number;\n keywordCount: number;\n validationTimeMs: number;\n };\n}\n\nexport interface FormatSchemaReferenceResolvedResult extends CanonicalReferenceResolvedResult<Record<string, unknown>> {\n kind: 'format_schema';\n schemaMeta: NonNullable<CanonicalReferenceResolvedResult['schemaMeta']>;\n}\n\nexport interface CanonicalReferenceFailureResult extends CanonicalReferenceResultBase {\n ok: false;\n status: Exclude<CanonicalReferenceStatus, 'resolved'>;\n error: CanonicalReferenceError;\n httpStatus?: number;\n}\n\nexport type CanonicalReferenceResult<TDocument = unknown> =\n | CanonicalReferenceResolvedResult<TDocument>\n | CanonicalReferenceFailureResult;\n\nexport type FormatSchemaReferenceResult = FormatSchemaReferenceResolvedResult | CanonicalReferenceFailureResult;\nexport type PlatformExtensionsReferenceResult = CanonicalReferenceResult<unknown>;\n\nexport type ExternalRefDigestMap = ReadonlyMap<string, string> | Readonly<Record<string, string>>;\n\nexport interface CanonicalReferenceCache {\n get(key: string): CanonicalReferenceResolvedResult | undefined;\n set(key: string, value: CanonicalReferenceResolvedResult): void;\n}\n\nexport interface CanonicalReferenceResolverOptions {\n /** Caller-owned cache. Defaults to a fresh per-resolver Map. */\n cache?: CanonicalReferenceCache;\n /** Default 5_000 ms. */\n timeoutMs?: number;\n /** Default 1 MiB. */\n maxBodyBytes?: number;\n /** Test/dev-only escape hatch for loopback fixtures. Production callers should leave false. */\n allowUnsafeHttp?: boolean;\n /** Test/dev-only escape hatch for loopback/private-network fixtures. Production callers should leave false. */\n allowPrivateNetwork?: boolean;\n /** Default 8 for `format_schema` `$ref` walks. */\n maxRefDepth?: number;\n /** Default 256 for `format_schema` `$ref` walks. */\n maxRefCount?: number;\n /** Default 10_000 approximate schema keyword/object-key bound. */\n maxKeywords?: number;\n /** Default 250 ms soft compile-time budget for JSON Schema validation. */\n validationBudgetMs?: number;\n /** Required for each external `$ref` URI in `format_schema`; keeps transitive schemas immutable. */\n externalRefDigests?: ExternalRefDigestMap;\n /** Default 8 MiB cumulative cap across external `$ref` bodies. */\n maxTotalRefBytes?: number;\n /** Default 5_000 ms total wall-clock budget across external `$ref` resolution. */\n maxRefResolutionMs?: number;\n /** Override the trusted mirror host set for `format_schema` external `$ref`s. */\n mirrorHosts?: readonly string[];\n /** Single-host convenience override for `format_schema` external `$ref`s. */\n mirrorHost?: string;\n}\n\nexport interface CanonicalReferenceResolveOptions extends Omit<CanonicalReferenceResolverOptions, 'cache'> {\n cache?: CanonicalReferenceCache;\n kind?: CanonicalReferenceKind;\n}\n\nexport interface CanonicalReferenceResolver {\n cache: CanonicalReferenceCache;\n resolveFormatSchema(\n ref: CanonicalReference,\n options?: Omit<CanonicalReferenceResolveOptions, 'cache' | 'kind'>\n ): Promise<FormatSchemaReferenceResult>;\n resolvePlatformExtensions(\n ref: CanonicalReference,\n options?: Omit<CanonicalReferenceResolveOptions, 'cache' | 'kind'>\n ): Promise<CanonicalReferenceResult<unknown>>;\n resolve(\n ref: CanonicalReference,\n options?: Omit<CanonicalReferenceResolveOptions, 'cache'>\n ): Promise<CanonicalReferenceResult<unknown>>;\n}\n\nconst DEFAULT_TIMEOUT_MS = 5_000;\nconst DEFAULT_MAX_BODY_BYTES = 1024 * 1024;\nconst DEFAULT_MAX_TOTAL_REF_BYTES = 8 * 1024 * 1024;\nconst DIGEST_RE = /^sha256:[0-9a-f]{64}$/;\nconst DRAFT_07_URIS = new Set(['http://json-schema.org/draft-07/schema#', 'https://json-schema.org/draft-07/schema#']);\nconst DRAFT_2020_12_URIS = new Set([\n 'https://json-schema.org/draft/2020-12/schema',\n 'https://json-schema.org/draft/2020-12/schema#',\n]);\nconst SPECIAL_USE_HOSTS = new Set([\n 'localhost',\n 'example',\n 'example.com',\n 'example.net',\n 'example.org',\n 'home.arpa',\n 'invalid',\n 'local',\n 'test',\n]);\n\nexport function createCanonicalReferenceCache(): CanonicalReferenceCache {\n const store = new Map<string, CanonicalReferenceResolvedResult>();\n return {\n get: key => store.get(key),\n set: (key, value) => {\n store.set(key, value);\n },\n };\n}\n\nexport function canonicalReferenceCacheKey(\n ref: CanonicalReference,\n options: Pick<CanonicalReferenceResolveOptions, 'allowPrivateNetwork' | 'allowUnsafeHttp' | 'maxBodyBytes'> = {}\n): string {\n const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;\n const privateNetwork = options.allowPrivateNetwork === true ? 1 : 0;\n const unsafeHttp = options.allowUnsafeHttp === true ? 1 : 0;\n return `${ref.uri}@${ref.digest}#priv=${privateNetwork}#http=${unsafeHttp}#max=${maxBodyBytes}`;\n}\n\nfunction cloneResolved<TDocument>(\n result: CanonicalReferenceResolvedResult<TDocument>\n): CanonicalReferenceResolvedResult<TDocument> {\n return {\n ...result,\n ref: { ...result.ref },\n body: Uint8Array.from(result.body),\n document: structuredClone(result.document),\n schemaMeta: result.schemaMeta ? { ...result.schemaMeta } : undefined,\n };\n}\n\nexport function createCanonicalReferenceResolver(\n defaults: CanonicalReferenceResolverOptions = {}\n): CanonicalReferenceResolver {\n const cache = defaults.cache ?? createCanonicalReferenceCache();\n const merge = (options: Omit<CanonicalReferenceResolveOptions, 'cache'> = {}): CanonicalReferenceResolveOptions => ({\n ...defaults,\n ...options,\n cache,\n });\n return {\n cache,\n resolveFormatSchema: (ref, options) =>\n resolveFormatSchemaReference(ref, merge({ ...options, kind: 'format_schema' })),\n resolvePlatformExtensions: (ref, options) =>\n resolvePlatformExtensionsReference(ref, merge({ ...options, kind: 'platform_extensions' })),\n resolve: (ref, options) => resolveCanonicalReference(ref, merge(options)),\n };\n}\n\nexport async function resolvePlatformExtensionsReference(\n ref: CanonicalReference,\n options: CanonicalReferenceResolveOptions = {}\n): Promise<PlatformExtensionsReferenceResult> {\n return resolveCanonicalReference(ref, { ...options, kind: 'platform_extensions' });\n}\n\nexport async function resolveFormatSchemaReference(\n ref: CanonicalReference,\n options: CanonicalReferenceResolveOptions = {}\n): Promise<FormatSchemaReferenceResult> {\n const fetched = await fetchJsonReference(ref, { ...options, kind: 'format_schema' });\n if (!fetched.ok) return fetched;\n if (!fetched.document || typeof fetched.document !== 'object' || Array.isArray(fetched.document)) {\n return fail(\n 'format_schema',\n ref,\n fetched.cacheKey,\n 'invalid_schema',\n 'invalid_json',\n 'format_schema must be a JSON object'\n );\n }\n\n const schema = fetched.document as Record<string, unknown>;\n const validated = await validateFormatSchema(schema, ref.uri, options);\n if (!validated.ok) {\n return {\n ok: false,\n status: validated.status ?? 'invalid_schema',\n kind: 'format_schema',\n ref,\n cacheKey: fetched.cacheKey,\n fromCache: false,\n error: validated.error,\n };\n }\n\n return cloneResolved({\n ...fetched,\n kind: 'format_schema',\n document: validated.schema,\n schemaMeta: validated.meta,\n }) as FormatSchemaReferenceResolvedResult;\n}\n\nexport async function resolveCanonicalReference(\n ref: CanonicalReference,\n options: CanonicalReferenceResolveOptions = {}\n): Promise<CanonicalReferenceResult<unknown>> {\n return fetchJsonReference(ref, options);\n}\n\nasync function fetchJsonReference(\n ref: CanonicalReference,\n options: CanonicalReferenceResolveOptions\n): Promise<CanonicalReferenceResult<unknown>> {\n const kind = options.kind ?? 'generic';\n const valid = validateRef(ref, kind, options);\n if (!valid.ok) return valid.result;\n\n const cache = options.cache;\n const cacheKey = canonicalReferenceCacheKey(ref, options);\n const cached = cache?.get(cacheKey);\n if (cached) {\n return { ...cloneResolved(cached), kind, ref, cacheKey, fromCache: true };\n }\n\n let response;\n try {\n response = await ssrfSafeFetch(ref.uri, {\n method: 'GET',\n headers: { accept: 'application/json, application/schema+json' },\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n maxBodyBytes: options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES,\n allowPrivateIp: options.allowPrivateNetwork === true,\n });\n } catch (err) {\n if (err instanceof SsrfRefusedError) {\n if (err.code === 'body_exceeds_limit') {\n return fail(\n kind,\n ref,\n cacheKey,\n 'unresolvable',\n 'body_too_large',\n 'Response body exceeded the configured cap',\n {\n retryable: false,\n }\n );\n }\n if (SSRF_TRANSIENT_CODES.has(err.code)) {\n return fail(\n kind,\n ref,\n cacheKey,\n 'unresolvable',\n 'network_error',\n 'Transient network failure while fetching canonical reference',\n {\n retryable: true,\n }\n );\n }\n const blockedCode = err.code === 'non_https_without_opt_in' ? 'non_https_url' : 'unsafe_url';\n return fail(\n kind,\n ref,\n cacheKey,\n 'blocked_unsafe_url',\n blockedCode,\n 'Canonical reference URL was blocked by SSRF policy',\n {\n details: { ssrfCode: err.code, hostname: err.hostname },\n }\n );\n }\n return fail(\n kind,\n ref,\n cacheKey,\n 'unresolvable',\n 'network_error',\n 'Network failure while fetching canonical reference',\n {\n retryable: true,\n }\n );\n }\n\n if (response.status >= 300 && response.status < 400) {\n return fail(\n kind,\n ref,\n cacheKey,\n 'blocked_unsafe_url',\n 'redirect_blocked',\n 'HTTP redirects are disabled for canonical references',\n {\n httpStatus: response.status,\n }\n );\n }\n if (response.status < 200 || response.status >= 300) {\n return fail(\n kind,\n ref,\n cacheKey,\n 'unresolvable',\n 'http_error',\n `HTTP ${response.status} while fetching canonical reference`,\n {\n retryable: response.status >= 500 || response.status === 429,\n httpStatus: response.status,\n }\n );\n }\n\n const actualDigest = `sha256:${createHash('sha256').update(response.body).digest('hex')}`;\n if (actualDigest !== ref.digest) {\n return fail(kind, ref, cacheKey, 'digest_mismatch', 'digest_mismatch', 'Canonical reference digest mismatch', {\n securitySignal: 'substitution_attack',\n details: { actualDigest },\n });\n }\n\n const text = new TextDecoder('utf-8').decode(response.body);\n let document: unknown;\n try {\n document = JSON.parse(text);\n } catch {\n return fail(kind, ref, cacheKey, 'invalid_document', 'invalid_json', 'Canonical reference body is not valid JSON');\n }\n\n const result: CanonicalReferenceResolvedResult = {\n ok: true,\n status: 'resolved',\n kind,\n ref,\n cacheKey,\n fromCache: false,\n document,\n body: response.body,\n text,\n contentType: response.headers['content-type'],\n httpStatus: response.status,\n };\n const cachedResult = cloneResolved(result);\n cache?.set(cacheKey, cachedResult);\n return cloneResolved(cachedResult);\n}\n\nasync function fetchJsonReferenceDocument(\n ref: CanonicalReference,\n kind: CanonicalReferenceKind,\n options: CanonicalReferenceResolveOptions\n): Promise<CanonicalReferenceResult<unknown>> {\n return fetchJsonReference(ref, { ...options, kind });\n}\n\nfunction validateRef(\n ref: CanonicalReference,\n kind: CanonicalReferenceKind,\n options: CanonicalReferenceResolveOptions\n): { ok: true } | { ok: false; result: CanonicalReferenceFailureResult } {\n const fallbackRef: CanonicalReference = {\n uri: typeof ref?.uri === 'string' ? ref.uri : '<missing>',\n digest: typeof ref?.digest === 'string' ? ref.digest : '<missing>',\n };\n const cacheKey = canonicalReferenceCacheKey(fallbackRef, options);\n if (!ref || typeof ref.uri !== 'string' || typeof ref.digest !== 'string') {\n return {\n ok: false,\n result: fail(\n kind,\n fallbackRef,\n cacheKey,\n 'invalid_ref',\n 'invalid_ref',\n 'Canonical reference must carry { uri, digest }'\n ),\n };\n }\n if (!DIGEST_RE.test(ref.digest)) {\n return {\n ok: false,\n result: fail(\n kind,\n ref,\n cacheKey,\n 'invalid_ref',\n 'invalid_ref',\n 'Canonical reference digest must be `sha256:` plus 64 lowercase hex characters'\n ),\n };\n }\n let parsed: URL;\n try {\n parsed = new URL(ref.uri);\n } catch {\n return {\n ok: false,\n result: fail(kind, ref, cacheKey, 'invalid_ref', 'invalid_ref', 'Canonical reference URI is not a valid URL'),\n };\n }\n const specialUseHost = specialUseHostname(parsed.hostname);\n if (specialUseHost) {\n return {\n ok: false,\n result: fail(\n kind,\n ref,\n cacheKey,\n 'blocked_unsafe_url',\n 'unsafe_url',\n 'Canonical reference URI uses a special-use hostname',\n { details: { hostname: specialUseHost } }\n ),\n };\n }\n if (parsed.protocol !== 'https:') {\n if (parsed.protocol === 'http:' && options.allowUnsafeHttp === true) return { ok: true };\n return {\n ok: false,\n result: fail(\n kind,\n ref,\n cacheKey,\n 'blocked_unsafe_url',\n 'non_https_url',\n 'Canonical reference URI must use https://'\n ),\n };\n }\n return { ok: true };\n}\n\nfunction specialUseHostname(hostname: string): string | null {\n const host = hostname\n .replace(/^\\[|\\]$/g, '')\n .toLowerCase()\n .replace(/\\.$/, '');\n if (SPECIAL_USE_HOSTS.has(host)) return host;\n if (host.endsWith('.example')) return host;\n if (host.endsWith('.home.arpa')) return host;\n if (host.endsWith('.localhost')) return host;\n if (host.endsWith('.local')) return host;\n if (host.endsWith('.invalid')) return host;\n if (host.endsWith('.test')) return host;\n if (host.endsWith('.example.com')) return host;\n if (host.endsWith('.example.net')) return host;\n if (host.endsWith('.example.org')) return host;\n return null;\n}\n\nfunction fail(\n kind: CanonicalReferenceKind,\n ref: CanonicalReference,\n cacheKey: string,\n status: Exclude<CanonicalReferenceStatus, 'resolved'>,\n code: CanonicalReferenceErrorCode,\n message: string,\n options: {\n retryable?: boolean;\n securitySignal?: 'substitution_attack';\n details?: Record<string, unknown>;\n httpStatus?: number;\n } = {}\n): CanonicalReferenceFailureResult {\n return {\n ok: false,\n status,\n kind,\n ref,\n cacheKey,\n fromCache: false,\n httpStatus: options.httpStatus,\n error: {\n code,\n message,\n retryable: options.retryable ?? false,\n securitySignal: options.securitySignal,\n details: options.details,\n },\n };\n}\n\ntype FormatSchemaValidation =\n | {\n ok: true;\n schema: Record<string, unknown>;\n meta: NonNullable<CanonicalReferenceResolvedResult['schemaMeta']>;\n }\n | { ok: false; status?: Exclude<CanonicalReferenceStatus, 'resolved'>; error: CanonicalReferenceError };\n\nasync function validateFormatSchema(\n schema: Record<string, unknown>,\n parentUri: string,\n options: CanonicalReferenceResolveOptions\n): Promise<FormatSchemaValidation> {\n const draft = detectDraft(schema);\n if (!draft.ok) return { ok: false, error: draft.error };\n\n let resolved;\n try {\n resolved = await resolveSchemaRefs(schema, parentUri, {\n maxDepth: options.maxRefDepth ?? DEFAULT_MAX_REF_DEPTH,\n maxRefCount: options.maxRefCount ?? DEFAULT_MAX_REF_COUNT,\n maxBodyBytes: options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n mirrorHost: options.mirrorHost,\n mirrorHosts: options.mirrorHosts,\n fetchExternal: makeExternalSchemaFetcher(options),\n } satisfies ResolveSchemaRefsOptions);\n } catch (err) {\n if (err instanceof SchemaRefSandboxError) {\n const mapped = canonicalFailureFromSchemaRefError(err);\n if (mapped) {\n return {\n ok: false,\n status: mapped.status,\n error: mapped.error,\n };\n }\n return {\n ok: false,\n status: 'invalid_schema',\n error: {\n code: 'ref_sandbox_violation',\n message: 'format_schema $ref sandbox rejected a reference',\n retryable: false,\n details: { sandboxCode: err.code, ref: err.ref },\n },\n };\n }\n return {\n ok: false,\n status: 'invalid_schema',\n error: { code: 'invalid_json_schema', message: 'format_schema $ref resolution failed', retryable: false },\n };\n }\n\n const keywordCount = countSchemaKeywords(resolved.schema);\n const maxKeywords = options.maxKeywords ?? DEFAULT_MAX_KEYWORDS;\n if (keywordCount > maxKeywords) {\n return {\n ok: false,\n error: {\n code: 'keyword_limit_exceeded',\n message: `format_schema keyword count exceeded ${maxKeywords}`,\n retryable: false,\n details: { keywordCount, maxKeywords },\n },\n };\n }\n\n const unsafeRegex = findUnsafeRegexPattern(resolved.schema);\n if (unsafeRegex) {\n return {\n ok: false,\n error: {\n code: 'budget_exceeded',\n message: 'format_schema regex safety budget exceeded',\n retryable: false,\n details: unsafeRegexDetails(unsafeRegex),\n },\n };\n }\n\n const ajv = draft.draft === '2020-12' ? getDraft2020Ajv() : getDraft07Ajv();\n const started = process.cpuUsage();\n try {\n ajv.compile(resolved.schema);\n } catch (err) {\n return {\n ok: false,\n error: {\n code: 'invalid_json_schema',\n message: 'format_schema is not a valid JSON Schema document',\n retryable: false,\n details: { reason: err instanceof Error ? err.message : String(err) },\n },\n };\n }\n // Ajv compilation is synchronous; CPU time avoids false budget failures when\n // the process is descheduled during highly parallel test or CI runs.\n const validationTimeMs = cpuUsageMs(started);\n const validationBudgetMs = options.validationBudgetMs ?? DEFAULT_VALIDATION_BUDGET_MS;\n if (validationTimeMs > validationBudgetMs) {\n return {\n ok: false,\n error: {\n code: 'invalid_json_schema',\n message: `format_schema compile exceeded ${validationBudgetMs} ms validation budget`,\n retryable: false,\n details: { validationTimeMs, validationBudgetMs },\n },\n };\n }\n\n return {\n ok: true,\n schema: resolved.schema,\n meta: {\n draft: draft.draft,\n refCount: resolved.refCount,\n maxRefDepthSeen: resolved.maxDepthSeen,\n keywordCount,\n validationTimeMs,\n },\n };\n}\n\nfunction cpuUsageMs(started: NodeJS.CpuUsage): number {\n const elapsed = process.cpuUsage(started);\n return (elapsed.user + elapsed.system) / 1000;\n}\n\nfunction detectDraft(\n schema: Record<string, unknown>\n): { ok: true; draft: 'draft-07' | '2020-12' } | { ok: false; error: CanonicalReferenceError } {\n const raw = schema.$schema;\n if (raw === undefined) {\n return {\n ok: false,\n error: {\n code: 'unsupported_schema_draft',\n message: 'format_schema must declare $schema',\n retryable: false,\n },\n };\n }\n if (typeof raw !== 'string') {\n return {\n ok: false,\n error: {\n code: 'unsupported_schema_draft',\n message: 'format_schema.$schema must be a JSON Schema draft URI string',\n retryable: false,\n },\n };\n }\n if (DRAFT_07_URIS.has(raw)) return { ok: true, draft: 'draft-07' };\n if (DRAFT_2020_12_URIS.has(raw)) return { ok: true, draft: '2020-12' };\n return {\n ok: false,\n error: {\n code: 'unsupported_schema_draft',\n message: 'format_schema must declare Draft-07 or Draft 2020-12',\n retryable: false,\n details: { schema: raw },\n },\n };\n}\n\nfunction getDraft07Ajv(): Ajv {\n const ajv = new Ajv({\n strict: false,\n allErrors: true,\n validateSchema: true,\n validateFormats: true,\n addUsedSchema: false,\n });\n addFormats(ajv);\n return ajv;\n}\n\nfunction getDraft2020Ajv(): InstanceType<typeof Ajv2020> {\n const ajv = new Ajv2020({\n strict: false,\n allErrors: true,\n validateSchema: true,\n validateFormats: true,\n addUsedSchema: false,\n });\n addFormats(ajv);\n return ajv;\n}\n\ntype MappedSchemaRefFailure = {\n status: Exclude<CanonicalReferenceStatus, 'resolved'>;\n error: CanonicalReferenceError;\n};\n\nfunction canonicalFailureFromSchemaRefError(err: SchemaRefSandboxError): MappedSchemaRefFailure | null {\n const details = err.details as\n | {\n canonicalStatus?: Exclude<CanonicalReferenceStatus, 'resolved'>;\n canonicalErrorCode?: CanonicalReferenceErrorCode;\n retryable?: boolean;\n securitySignal?: 'substitution_attack';\n details?: Record<string, unknown>;\n }\n | undefined;\n if (!details?.canonicalStatus || !details.canonicalErrorCode) return null;\n return {\n status: details.canonicalStatus,\n error: {\n code: details.canonicalErrorCode,\n message: err.message,\n retryable: details.retryable === true,\n securitySignal: details.securitySignal,\n details: { ref: err.ref, ...details.details },\n },\n };\n}\n\nfunction makeExternalSchemaFetcher(\n options: CanonicalReferenceResolveOptions\n): (uri: string) => Promise<Record<string, unknown>> {\n const deadlineMs = Date.now() + (options.maxRefResolutionMs ?? DEFAULT_TIMEOUT_MS);\n const maxTotalRefBytes = options.maxTotalRefBytes ?? DEFAULT_MAX_TOTAL_REF_BYTES;\n let totalRefBytes = 0;\n\n return async uri => {\n const expectedDigest = lookupExternalRefDigest(options.externalRefDigests, uri);\n if (!expectedDigest) {\n throwExternalRefFailure(uri, 'invalid_schema', 'external_ref_unpinned', 'External $ref missing pinned digest');\n }\n const refValidation = validateRef({ uri, digest: expectedDigest }, 'format_schema', options);\n if (!refValidation.ok) {\n throwExternalRefFailure(\n uri,\n refValidation.result.status,\n refValidation.result.error.code,\n refValidation.result.error.message,\n {\n retryable: refValidation.result.error.retryable,\n securitySignal: refValidation.result.error.securitySignal,\n details: refValidation.result.error.details,\n }\n );\n }\n const remainingMs = deadlineMs - Date.now();\n if (remainingMs <= 0) {\n throwExternalRefFailure(uri, 'unresolvable', 'network_error', 'External $ref resolution budget exceeded', {\n retryable: true,\n });\n }\n\n const fetched = await fetchJsonReferenceDocument({ uri, digest: expectedDigest }, 'format_schema', {\n ...options,\n timeoutMs: Math.min(options.timeoutMs ?? DEFAULT_TIMEOUT_MS, remainingMs),\n });\n if (!fetched.ok) {\n throwExternalRefFailure(\n uri,\n fetched.status,\n fetched.error.code,\n `External $ref fetch failed: ${fetched.error.message}`,\n {\n retryable: fetched.error.retryable,\n securitySignal: fetched.error.securitySignal,\n details: {\n ...fetched.error.details,\n ...(fetched.httpStatus === undefined ? {} : { httpStatus: fetched.httpStatus }),\n },\n }\n );\n }\n totalRefBytes += fetched.body.byteLength;\n if (totalRefBytes > maxTotalRefBytes) {\n throwExternalRefFailure(uri, 'unresolvable', 'body_too_large', 'External $ref total body budget exceeded', {\n details: { totalRefBytes, maxTotalRefBytes },\n });\n }\n if (!fetched.document || typeof fetched.document !== 'object' || Array.isArray(fetched.document)) {\n throwExternalRefFailure(uri, 'invalid_schema', 'invalid_json', 'External $ref body is not a JSON object');\n }\n return fetched.document as Record<string, unknown>;\n };\n}\n\nfunction lookupExternalRefDigest(digests: ExternalRefDigestMap | undefined, uri: string): string | undefined {\n if (!digests) return undefined;\n if (typeof (digests as ReadonlyMap<string, string>).get === 'function') {\n return (digests as ReadonlyMap<string, string>).get(uri);\n }\n return (digests as Readonly<Record<string, string>>)[uri];\n}\n\nfunction throwExternalRefFailure(\n uri: string,\n status: Exclude<CanonicalReferenceStatus, 'resolved'>,\n code: CanonicalReferenceErrorCode,\n message: string,\n options: {\n retryable?: boolean;\n securitySignal?: 'substitution_attack';\n details?: Record<string, unknown>;\n } = {}\n): never {\n throw new SchemaRefSandboxError('fetch_failed', message, {\n ref: uri,\n details: {\n canonicalStatus: status,\n canonicalErrorCode: code,\n retryable: options.retryable === true,\n securitySignal: options.securitySignal,\n details: options.details,\n },\n });\n}\n\nfunction countSchemaKeywords(root: unknown): number {\n const seen = new Set<unknown>();\n const walk = (node: unknown): number => {\n if (!node || typeof node !== 'object') return 0;\n if (seen.has(node)) return 0;\n seen.add(node);\n if (Array.isArray(node)) return node.reduce((sum, item) => sum + walk(item), 0);\n const obj = node as Record<string, unknown>;\n return Object.entries(obj).reduce((sum, [, value]) => sum + 1 + walk(value), 0);\n };\n return walk(root);\n}\n"],"mappings":"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","names":["require"]}
|
|
@@ -1,8 +1,2 @@
|
|
|
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
|
export * from "../index.mjs";
|
|
8
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/client/index.ts"],"sourcesContent":["// AdCP SDK — client surface\n//\n// Buyer-side: instantiate clients to call AdCP agents over MCP/A2A,\n// orchestrate multi-agent flows, and inspect responses.\n//\n// `import { AdcpClient } from '@adcp/sdk'` and\n// `import { AdcpClient } from '@adcp/sdk/client'` resolve to the same surface.\n// The subpath exists for symmetry with `/server` and `/compliance`.\n\nexport * from '../index';\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/client/index.ts"],"sourcesContent":["// AdCP SDK — client surface\n//\n// Buyer-side: instantiate clients to call AdCP agents over MCP/A2A,\n// orchestrate multi-agent flows, and inspect responses.\n//\n// `import { AdcpClient } from '@adcp/sdk'` and\n// `import { AdcpClient } from '@adcp/sdk/client'` resolve to the same surface.\n// The subpath exists for symmetry with `/server` and `/compliance`.\n\nexport * from '../index';\n"],"mappings":"AASA,cAAc;","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
|
export * from "../testing/index.mjs";
|
|
8
2
|
export * from "../conformance/index.mjs";
|
|
9
3
|
export * from "../compliance-fixtures/index.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/compliance/index.ts"],"sourcesContent":["// AdCP SDK — compliance harness\n//\n// Umbrella entry that re-exports the four compliance-related modules:\n//\n// - `testing`: pre-configured test agents, agent-tester scenarios,\n// storyboard runner + parser, controller assertions, comply-controller\n// scaffold, seed-merge helpers, brief library. Largest surface; about\n// 60 symbols.\n// - `conformance`: property-based fuzzer driven by published JSON schemas\n// (`runConformance`, `seedFixtures`, tier constants).\n// - `compliance-fixtures`: canonical storyboard fixtures keyed by ID\n// (`COMPLIANCE_FIXTURES`, `seedComplianceFixtures`,\n// `COMPLIANCE_COLLECTIONS`).\n// - `signing/testing`: in-memory signing provider for conformance runs\n// (`InMemorySigningProvider`, `ALLOW_IN_MEMORY_SIGNER_ENV`).\n//\n// Why an umbrella: a compliance harness usually wants all four. Keeping\n// each subpath separately importable — `@adcp/sdk/testing`,\n// `@adcp/sdk/conformance`, etc. — preserves the bundle-cost escape hatch\n// for callers who only need one piece (so `fast-check` and the schema\n// bundle don't load when you just want test agents).\n//\n// **Collision safety.** `export *` lets TypeScript enforce TS2308 at\n// compile time if two sources ever try to re-export the same name. A\n// future PR that adds (e.g.) `seedFixtures` to `testing` would fail the\n// build until either the `testing` export is renamed or one source\n// drops it — there's no silent shadowing path. The `compliance-umbrella`\n// smoke test (test/lib/compliance-umbrella.test.js) additionally asserts\n// a representative set of symbols stay visible across the four sources,\n// so an accidental removal from one of them surfaces as a test failure\n// rather than as a missing import in a downstream consumer.\n\nexport * from '../testing';\nexport * from '../conformance';\nexport * from '../compliance-fixtures';\nexport * from '../signing/testing';\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/compliance/index.ts"],"sourcesContent":["// AdCP SDK — compliance harness\n//\n// Umbrella entry that re-exports the four compliance-related modules:\n//\n// - `testing`: pre-configured test agents, agent-tester scenarios,\n// storyboard runner + parser, controller assertions, comply-controller\n// scaffold, seed-merge helpers, brief library. Largest surface; about\n// 60 symbols.\n// - `conformance`: property-based fuzzer driven by published JSON schemas\n// (`runConformance`, `seedFixtures`, tier constants).\n// - `compliance-fixtures`: canonical storyboard fixtures keyed by ID\n// (`COMPLIANCE_FIXTURES`, `seedComplianceFixtures`,\n// `COMPLIANCE_COLLECTIONS`).\n// - `signing/testing`: in-memory signing provider for conformance runs\n// (`InMemorySigningProvider`, `ALLOW_IN_MEMORY_SIGNER_ENV`).\n//\n// Why an umbrella: a compliance harness usually wants all four. Keeping\n// each subpath separately importable — `@adcp/sdk/testing`,\n// `@adcp/sdk/conformance`, etc. — preserves the bundle-cost escape hatch\n// for callers who only need one piece (so `fast-check` and the schema\n// bundle don't load when you just want test agents).\n//\n// **Collision safety.** `export *` lets TypeScript enforce TS2308 at\n// compile time if two sources ever try to re-export the same name. A\n// future PR that adds (e.g.) `seedFixtures` to `testing` would fail the\n// build until either the `testing` export is renamed or one source\n// drops it — there's no silent shadowing path. The `compliance-umbrella`\n// smoke test (test/lib/compliance-umbrella.test.js) additionally asserts\n// a representative set of symbols stay visible across the four sources,\n// so an accidental removal from one of them surfaces as a test failure\n// rather than as a missing import in a downstream consumer.\n\nexport * from '../testing';\nexport * from '../conformance';\nexport * from '../compliance-fixtures';\nexport * from '../signing/testing';\n"],"mappings":"AAgCA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","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 { ADCP_STATE_STORE } from "../server/adcp-server.mjs";
|
|
8
2
|
const COMPLIANCE_COLLECTIONS = Object.freeze({
|
|
9
3
|
products: "compliance:products",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/compliance-fixtures/index.ts"],"sourcesContent":["/**\n * Canonical AdCP compliance storyboard fixtures.\n *\n * Conformance storyboards reference entities by hardcoded ID —\n * `test-product`, `test-pricing`, `video_30s`, `native_post`,\n * `native_content`, `campaign_hero_video`, `sports_ctv_q2`,\n * `cpm_guaranteed`, `gov_acme_q2_2027`, `mb_acme_q2_2026_auction`,\n * and a handful of others. None are discoverable from the JSON\n * Schemas alone; every implementer hits the same wall (failing\n * storyboards → grep YAML source → hand-seed matching fixtures).\n *\n * This module owns the canonical data and offers two integration\n * paths:\n *\n * - {@link COMPLIANCE_FIXTURES}: a typed object literal with every\n * known fixture ID and a minimal-but-storyboard-compatible body.\n * Sellers can merge these into whatever handlers answer the\n * relevant tools (`get_products`, `list_creative_formats`,\n * `list_creatives`, …).\n *\n * - {@link seedComplianceFixtures}: writes the fixtures into the\n * server's state store under well-known collection names (see\n * {@link COMPLIANCE_COLLECTIONS}). Sellers whose handlers already\n * read-through the state store get fixtures populated without\n * touching handler code.\n *\n * ```ts\n * import { createAdcpServer } from '@adcp/sdk/server/legacy/v5';\n * import { seedComplianceFixtures, COMPLIANCE_FIXTURES } from '@adcp/sdk/compliance-fixtures';\n *\n * const server = createAdcpServer({\n * mediaBuy: {\n * getProducts: async (_params, ctx) => ({\n * products: [\n * ...(await ctx.store.list('compliance:products')).items.map(r => r.value),\n * ...myCatalog,\n * ],\n * }),\n * },\n * ...handlers,\n * });\n *\n * await seedComplianceFixtures(server);\n * ```\n *\n * The shipped bodies are minimal on purpose: they contain exactly the\n * fields storyboards probe. Sellers whose catalog shape differs (richer\n * pricing, per-brand variants, etc.) SHOULD override via\n * {@link SeedComplianceFixturesOptions.overrides}.\n */\n\nimport { ADCP_STATE_STORE, type AdcpServer } from '../server/adcp-server';\nimport type { AdcpStateStore } from '../server/state-store';\n// Pull canonical shapes from the generated spec types so fixture typings\n// can't drift from the schema. `PricingOption` is the discriminated\n// union (`CPMPricingOption | VCPMPricingOption | ...`) — typing\n// fixture bodies as this union gives consumers full TS narrowing and\n// guarantees the fixture matches at least one spec variant.\nimport type { PricingOption } from '../types/tools.generated';\n\nexport type ComplianceFixtureCategory =\n | 'products'\n | 'formats'\n | 'creatives'\n | 'plans'\n | 'media_buys'\n | 'pricing_options';\n\n/**\n * State-store collection names the seeder writes into. Handlers that\n * read-through the state store should use the same names when\n * integrating fixture data into their own responses.\n */\nexport const COMPLIANCE_COLLECTIONS: Readonly<Record<ComplianceFixtureCategory, string>> = Object.freeze({\n products: 'compliance:products',\n formats: 'compliance:formats',\n creatives: 'compliance:creatives',\n plans: 'compliance:plans',\n media_buys: 'compliance:media_buys',\n pricing_options: 'compliance:pricing_options',\n});\n\nexport interface ComplianceProductFixture {\n product_id: string;\n name: string;\n description: string;\n delivery_type: 'guaranteed' | 'non_guaranteed';\n channels: string[];\n formats: string[];\n pricing_options: string[];\n}\n\nexport interface ComplianceFormatFixture {\n format_id: string;\n name: string;\n type: string;\n width?: number;\n height?: number;\n duration_ms?: number;\n}\n\n/**\n * Fixture body for a pricing option. Aliases the spec's discriminated\n * `PricingOption` union so callers that spread a fixture into a\n * `get_products` response get full TypeScript narrowing on\n * `pricing_model`. The shipped bodies are all `CPMPricingOption`\n * (fixed-price CPM); sellers who need other variants should supply\n * overrides via {@link SeedComplianceFixturesOptions.overrides}.\n */\nexport type CompliancePricingOptionFixture = PricingOption;\n\nexport interface ComplianceCreativeFixture {\n creative_id: string;\n format_id: string;\n status: 'approved' | 'pending' | 'rejected';\n name: string;\n}\n\nexport interface CompliancePlanFixture {\n plan_id: string;\n brand_domain: string;\n total_budget: { amount: number; currency: string };\n status: 'active' | 'paused';\n}\n\nexport interface ComplianceMediaBuyFixture {\n media_buy_id: string;\n status: 'active' | 'pending_start' | 'completed';\n total_budget: { amount: number; currency: string };\n}\n\nexport interface ComplianceFixtureSet {\n products: Readonly<Record<string, Readonly<ComplianceProductFixture>>>;\n formats: Readonly<Record<string, Readonly<ComplianceFormatFixture>>>;\n pricing_options: Readonly<Record<string, Readonly<CompliancePricingOptionFixture>>>;\n creatives: Readonly<Record<string, Readonly<ComplianceCreativeFixture>>>;\n plans: Readonly<Record<string, Readonly<CompliancePlanFixture>>>;\n media_buys: Readonly<Record<string, Readonly<ComplianceMediaBuyFixture>>>;\n}\n\n/**\n * Canonical storyboard fixtures. Every ID here appears verbatim in at\n * least one `compliance/cache/latest/**\\/*.yaml` storyboard — CI lints\n * the tie between source storyboards and this set (not yet; see\n * {@link https://github.com/adcontextprotocol/adcp-client/issues/663}).\n */\nexport const COMPLIANCE_FIXTURES: ComplianceFixtureSet = Object.freeze({\n products: Object.freeze({\n 'test-product': Object.freeze({\n product_id: 'test-product',\n name: 'Test Product',\n description:\n 'Generic non-guaranteed inventory used by universal storyboards (error-compliance, idempotency, deterministic-testing, schema-validation).',\n delivery_type: 'non_guaranteed',\n channels: ['display', 'video'],\n formats: ['video_30s', 'native_post', 'native_content'],\n pricing_options: ['test-pricing', 'default'],\n }),\n sports_ctv_q2: Object.freeze({\n product_id: 'sports_ctv_q2',\n name: 'Sports CTV — Q2',\n description: 'CTV variant referenced by governance-spend-authority and governance-delivery-monitor storyboards.',\n delivery_type: 'guaranteed',\n channels: ['ctv'],\n formats: ['video_30s'],\n pricing_options: ['cpm_guaranteed'],\n }),\n }),\n\n formats: Object.freeze({\n video_30s: Object.freeze({\n format_id: 'video_30s',\n name: '30-second Video',\n type: 'video',\n duration_ms: 30_000,\n }),\n native_post: Object.freeze({\n format_id: 'native_post',\n name: 'Native Post',\n type: 'native',\n }),\n native_content: Object.freeze({\n format_id: 'native_content',\n name: 'Native Content',\n type: 'native',\n }),\n }),\n\n pricing_options: Object.freeze({\n 'test-pricing': Object.freeze({\n pricing_option_id: 'test-pricing',\n currency: 'USD',\n pricing_model: 'cpm',\n fixed_price: 5,\n }),\n default: Object.freeze({\n pricing_option_id: 'default',\n currency: 'USD',\n pricing_model: 'cpm',\n fixed_price: 10,\n }),\n cpm_guaranteed: Object.freeze({\n pricing_option_id: 'cpm_guaranteed',\n currency: 'USD',\n pricing_model: 'cpm',\n fixed_price: 25,\n }),\n }),\n\n creatives: Object.freeze({\n campaign_hero_video: Object.freeze({\n creative_id: 'campaign_hero_video',\n format_id: 'video_30s',\n status: 'approved',\n name: 'Campaign Hero Video',\n }),\n }),\n\n plans: Object.freeze({\n gov_acme_q2_2027: Object.freeze({\n plan_id: 'gov_acme_q2_2027',\n brand_domain: 'acmeoutdoor.example',\n total_budget: Object.freeze({ amount: 50_000, currency: 'USD' }),\n status: 'active',\n }),\n }),\n\n media_buys: Object.freeze({\n mb_acme_q2_2026_auction: Object.freeze({\n media_buy_id: 'mb_acme_q2_2026_auction',\n status: 'active',\n total_budget: Object.freeze({ amount: 25_000, currency: 'USD' }),\n }),\n }),\n}) as ComplianceFixtureSet;\n\nexport interface SeedComplianceFixturesOptions {\n /**\n * Subset of fixture categories to seed. Defaults to all six.\n */\n categories?: ComplianceFixtureCategory[];\n /**\n * Per-category overrides to merge ON TOP of the canonical fixtures.\n * Keys are the fixture IDs — replacing an entry with `null` deletes\n * it from the seed set (for sellers whose catalog shape legitimately\n * can't satisfy a given storyboard's expectations).\n */\n overrides?: {\n [K in ComplianceFixtureCategory]?: Record<string, ComplianceFixtureSet[K][string] | null>;\n };\n /**\n * Collection-name prefix override. Defaults to the\n * {@link COMPLIANCE_COLLECTIONS} defaults (`compliance:*`). Use when\n * your handlers already read from a different collection convention.\n */\n collections?: Partial<Record<ComplianceFixtureCategory, string>>;\n}\n\n/**\n * Write {@link COMPLIANCE_FIXTURES} into the server's state store\n * under {@link COMPLIANCE_COLLECTIONS}. Handlers that read from the\n * same collections get compliance fixtures without hand-seeding.\n *\n * Idempotent: re-seeding overwrites existing entries with the same ID\n * (the state store's `put` is the write primitive — no version check).\n * Between storyboards, call `server.compliance.reset()` to clear state\n * AND re-seed (reset itself doesn't restore fixtures).\n *\n * Throws when the server doesn't expose a state store with the shape\n * {@link AdcpStateStore}. Custom servers that wrap the MCP SDK directly\n * should use {@link COMPLIANCE_FIXTURES} as the source of truth and\n * wire seeding themselves.\n */\nexport async function seedComplianceFixtures(\n server: AdcpServer,\n options: SeedComplianceFixturesOptions = {}\n): Promise<void> {\n const store = resolveStateStore(server);\n const categories: ComplianceFixtureCategory[] =\n options.categories ?? (Object.keys(COMPLIANCE_COLLECTIONS) as ComplianceFixtureCategory[]);\n\n for (const category of categories) {\n const fixtures = COMPLIANCE_FIXTURES[category] as Record<string, Record<string, unknown>>;\n const overrides = (options.overrides?.[category] ?? {}) as Record<string, Record<string, unknown> | null>;\n const collection = options.collections?.[category] ?? COMPLIANCE_COLLECTIONS[category];\n\n const merged: Record<string, Record<string, unknown>> = { ...fixtures };\n for (const [id, override] of Object.entries(overrides)) {\n if (override === null) {\n delete merged[id];\n } else {\n merged[id] = override;\n }\n }\n\n for (const [id, body] of Object.entries(merged)) {\n await store.put(collection, id, body);\n }\n }\n}\n\n/**\n * Look up a single fixture by category and ID. Convenience for\n * handlers that don't want to iterate the entire fixture set.\n */\nexport function getComplianceFixture<K extends ComplianceFixtureCategory>(\n category: K,\n id: string\n): ComplianceFixtureSet[K][string] | undefined {\n return (COMPLIANCE_FIXTURES[category] as Record<string, ComplianceFixtureSet[K][string]>)[id];\n}\n\nfunction resolveStateStore(server: AdcpServer): AdcpStateStore {\n const candidate = (server as unknown as { [k: symbol]: unknown })[ADCP_STATE_STORE];\n if (isStateStore(candidate)) return candidate;\n throw new Error(\n 'seedComplianceFixtures: argument is not an AdcpServer produced by `createAdcpServer()`. ' +\n 'Use `COMPLIANCE_FIXTURES` directly and seed via your own integration path.'\n );\n}\n\nexport {\n createTestAuthorizationServer,\n type TestAuthorizationServer,\n type TestAuthorizationServerOptions,\n type IssueTokenOptions,\n} from './test-authorization-server';\n\nfunction isStateStore(value: unknown): value is AdcpStateStore {\n return (\n value != null &&\n typeof value === 'object' &&\n typeof (value as { put?: unknown }).put === 'function' &&\n typeof (value as { get?: unknown }).get === 'function' &&\n typeof (value as { list?: unknown }).list === 'function'\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/compliance-fixtures/index.ts"],"sourcesContent":["/**\n * Canonical AdCP compliance storyboard fixtures.\n *\n * Conformance storyboards reference entities by hardcoded ID —\n * `test-product`, `test-pricing`, `video_30s`, `native_post`,\n * `native_content`, `campaign_hero_video`, `sports_ctv_q2`,\n * `cpm_guaranteed`, `gov_acme_q2_2027`, `mb_acme_q2_2026_auction`,\n * and a handful of others. None are discoverable from the JSON\n * Schemas alone; every implementer hits the same wall (failing\n * storyboards → grep YAML source → hand-seed matching fixtures).\n *\n * This module owns the canonical data and offers two integration\n * paths:\n *\n * - {@link COMPLIANCE_FIXTURES}: a typed object literal with every\n * known fixture ID and a minimal-but-storyboard-compatible body.\n * Sellers can merge these into whatever handlers answer the\n * relevant tools (`get_products`, `list_creative_formats`,\n * `list_creatives`, …).\n *\n * - {@link seedComplianceFixtures}: writes the fixtures into the\n * server's state store under well-known collection names (see\n * {@link COMPLIANCE_COLLECTIONS}). Sellers whose handlers already\n * read-through the state store get fixtures populated without\n * touching handler code.\n *\n * ```ts\n * import { createAdcpServer } from '@adcp/sdk/server/legacy/v5';\n * import { seedComplianceFixtures, COMPLIANCE_FIXTURES } from '@adcp/sdk/compliance-fixtures';\n *\n * const server = createAdcpServer({\n * mediaBuy: {\n * getProducts: async (_params, ctx) => ({\n * products: [\n * ...(await ctx.store.list('compliance:products')).items.map(r => r.value),\n * ...myCatalog,\n * ],\n * }),\n * },\n * ...handlers,\n * });\n *\n * await seedComplianceFixtures(server);\n * ```\n *\n * The shipped bodies are minimal on purpose: they contain exactly the\n * fields storyboards probe. Sellers whose catalog shape differs (richer\n * pricing, per-brand variants, etc.) SHOULD override via\n * {@link SeedComplianceFixturesOptions.overrides}.\n */\n\nimport { ADCP_STATE_STORE, type AdcpServer } from '../server/adcp-server';\nimport type { AdcpStateStore } from '../server/state-store';\n// Pull canonical shapes from the generated spec types so fixture typings\n// can't drift from the schema. `PricingOption` is the discriminated\n// union (`CPMPricingOption | VCPMPricingOption | ...`) — typing\n// fixture bodies as this union gives consumers full TS narrowing and\n// guarantees the fixture matches at least one spec variant.\nimport type { PricingOption } from '../types/tools.generated';\n\nexport type ComplianceFixtureCategory =\n | 'products'\n | 'formats'\n | 'creatives'\n | 'plans'\n | 'media_buys'\n | 'pricing_options';\n\n/**\n * State-store collection names the seeder writes into. Handlers that\n * read-through the state store should use the same names when\n * integrating fixture data into their own responses.\n */\nexport const COMPLIANCE_COLLECTIONS: Readonly<Record<ComplianceFixtureCategory, string>> = Object.freeze({\n products: 'compliance:products',\n formats: 'compliance:formats',\n creatives: 'compliance:creatives',\n plans: 'compliance:plans',\n media_buys: 'compliance:media_buys',\n pricing_options: 'compliance:pricing_options',\n});\n\nexport interface ComplianceProductFixture {\n product_id: string;\n name: string;\n description: string;\n delivery_type: 'guaranteed' | 'non_guaranteed';\n channels: string[];\n formats: string[];\n pricing_options: string[];\n}\n\nexport interface ComplianceFormatFixture {\n format_id: string;\n name: string;\n type: string;\n width?: number;\n height?: number;\n duration_ms?: number;\n}\n\n/**\n * Fixture body for a pricing option. Aliases the spec's discriminated\n * `PricingOption` union so callers that spread a fixture into a\n * `get_products` response get full TypeScript narrowing on\n * `pricing_model`. The shipped bodies are all `CPMPricingOption`\n * (fixed-price CPM); sellers who need other variants should supply\n * overrides via {@link SeedComplianceFixturesOptions.overrides}.\n */\nexport type CompliancePricingOptionFixture = PricingOption;\n\nexport interface ComplianceCreativeFixture {\n creative_id: string;\n format_id: string;\n status: 'approved' | 'pending' | 'rejected';\n name: string;\n}\n\nexport interface CompliancePlanFixture {\n plan_id: string;\n brand_domain: string;\n total_budget: { amount: number; currency: string };\n status: 'active' | 'paused';\n}\n\nexport interface ComplianceMediaBuyFixture {\n media_buy_id: string;\n status: 'active' | 'pending_start' | 'completed';\n total_budget: { amount: number; currency: string };\n}\n\nexport interface ComplianceFixtureSet {\n products: Readonly<Record<string, Readonly<ComplianceProductFixture>>>;\n formats: Readonly<Record<string, Readonly<ComplianceFormatFixture>>>;\n pricing_options: Readonly<Record<string, Readonly<CompliancePricingOptionFixture>>>;\n creatives: Readonly<Record<string, Readonly<ComplianceCreativeFixture>>>;\n plans: Readonly<Record<string, Readonly<CompliancePlanFixture>>>;\n media_buys: Readonly<Record<string, Readonly<ComplianceMediaBuyFixture>>>;\n}\n\n/**\n * Canonical storyboard fixtures. Every ID here appears verbatim in at\n * least one `compliance/cache/latest/**\\/*.yaml` storyboard — CI lints\n * the tie between source storyboards and this set (not yet; see\n * {@link https://github.com/adcontextprotocol/adcp-client/issues/663}).\n */\nexport const COMPLIANCE_FIXTURES: ComplianceFixtureSet = Object.freeze({\n products: Object.freeze({\n 'test-product': Object.freeze({\n product_id: 'test-product',\n name: 'Test Product',\n description:\n 'Generic non-guaranteed inventory used by universal storyboards (error-compliance, idempotency, deterministic-testing, schema-validation).',\n delivery_type: 'non_guaranteed',\n channels: ['display', 'video'],\n formats: ['video_30s', 'native_post', 'native_content'],\n pricing_options: ['test-pricing', 'default'],\n }),\n sports_ctv_q2: Object.freeze({\n product_id: 'sports_ctv_q2',\n name: 'Sports CTV — Q2',\n description: 'CTV variant referenced by governance-spend-authority and governance-delivery-monitor storyboards.',\n delivery_type: 'guaranteed',\n channels: ['ctv'],\n formats: ['video_30s'],\n pricing_options: ['cpm_guaranteed'],\n }),\n }),\n\n formats: Object.freeze({\n video_30s: Object.freeze({\n format_id: 'video_30s',\n name: '30-second Video',\n type: 'video',\n duration_ms: 30_000,\n }),\n native_post: Object.freeze({\n format_id: 'native_post',\n name: 'Native Post',\n type: 'native',\n }),\n native_content: Object.freeze({\n format_id: 'native_content',\n name: 'Native Content',\n type: 'native',\n }),\n }),\n\n pricing_options: Object.freeze({\n 'test-pricing': Object.freeze({\n pricing_option_id: 'test-pricing',\n currency: 'USD',\n pricing_model: 'cpm',\n fixed_price: 5,\n }),\n default: Object.freeze({\n pricing_option_id: 'default',\n currency: 'USD',\n pricing_model: 'cpm',\n fixed_price: 10,\n }),\n cpm_guaranteed: Object.freeze({\n pricing_option_id: 'cpm_guaranteed',\n currency: 'USD',\n pricing_model: 'cpm',\n fixed_price: 25,\n }),\n }),\n\n creatives: Object.freeze({\n campaign_hero_video: Object.freeze({\n creative_id: 'campaign_hero_video',\n format_id: 'video_30s',\n status: 'approved',\n name: 'Campaign Hero Video',\n }),\n }),\n\n plans: Object.freeze({\n gov_acme_q2_2027: Object.freeze({\n plan_id: 'gov_acme_q2_2027',\n brand_domain: 'acmeoutdoor.example',\n total_budget: Object.freeze({ amount: 50_000, currency: 'USD' }),\n status: 'active',\n }),\n }),\n\n media_buys: Object.freeze({\n mb_acme_q2_2026_auction: Object.freeze({\n media_buy_id: 'mb_acme_q2_2026_auction',\n status: 'active',\n total_budget: Object.freeze({ amount: 25_000, currency: 'USD' }),\n }),\n }),\n}) as ComplianceFixtureSet;\n\nexport interface SeedComplianceFixturesOptions {\n /**\n * Subset of fixture categories to seed. Defaults to all six.\n */\n categories?: ComplianceFixtureCategory[];\n /**\n * Per-category overrides to merge ON TOP of the canonical fixtures.\n * Keys are the fixture IDs — replacing an entry with `null` deletes\n * it from the seed set (for sellers whose catalog shape legitimately\n * can't satisfy a given storyboard's expectations).\n */\n overrides?: {\n [K in ComplianceFixtureCategory]?: Record<string, ComplianceFixtureSet[K][string] | null>;\n };\n /**\n * Collection-name prefix override. Defaults to the\n * {@link COMPLIANCE_COLLECTIONS} defaults (`compliance:*`). Use when\n * your handlers already read from a different collection convention.\n */\n collections?: Partial<Record<ComplianceFixtureCategory, string>>;\n}\n\n/**\n * Write {@link COMPLIANCE_FIXTURES} into the server's state store\n * under {@link COMPLIANCE_COLLECTIONS}. Handlers that read from the\n * same collections get compliance fixtures without hand-seeding.\n *\n * Idempotent: re-seeding overwrites existing entries with the same ID\n * (the state store's `put` is the write primitive — no version check).\n * Between storyboards, call `server.compliance.reset()` to clear state\n * AND re-seed (reset itself doesn't restore fixtures).\n *\n * Throws when the server doesn't expose a state store with the shape\n * {@link AdcpStateStore}. Custom servers that wrap the MCP SDK directly\n * should use {@link COMPLIANCE_FIXTURES} as the source of truth and\n * wire seeding themselves.\n */\nexport async function seedComplianceFixtures(\n server: AdcpServer,\n options: SeedComplianceFixturesOptions = {}\n): Promise<void> {\n const store = resolveStateStore(server);\n const categories: ComplianceFixtureCategory[] =\n options.categories ?? (Object.keys(COMPLIANCE_COLLECTIONS) as ComplianceFixtureCategory[]);\n\n for (const category of categories) {\n const fixtures = COMPLIANCE_FIXTURES[category] as Record<string, Record<string, unknown>>;\n const overrides = (options.overrides?.[category] ?? {}) as Record<string, Record<string, unknown> | null>;\n const collection = options.collections?.[category] ?? COMPLIANCE_COLLECTIONS[category];\n\n const merged: Record<string, Record<string, unknown>> = { ...fixtures };\n for (const [id, override] of Object.entries(overrides)) {\n if (override === null) {\n delete merged[id];\n } else {\n merged[id] = override;\n }\n }\n\n for (const [id, body] of Object.entries(merged)) {\n await store.put(collection, id, body);\n }\n }\n}\n\n/**\n * Look up a single fixture by category and ID. Convenience for\n * handlers that don't want to iterate the entire fixture set.\n */\nexport function getComplianceFixture<K extends ComplianceFixtureCategory>(\n category: K,\n id: string\n): ComplianceFixtureSet[K][string] | undefined {\n return (COMPLIANCE_FIXTURES[category] as Record<string, ComplianceFixtureSet[K][string]>)[id];\n}\n\nfunction resolveStateStore(server: AdcpServer): AdcpStateStore {\n const candidate = (server as unknown as { [k: symbol]: unknown })[ADCP_STATE_STORE];\n if (isStateStore(candidate)) return candidate;\n throw new Error(\n 'seedComplianceFixtures: argument is not an AdcpServer produced by `createAdcpServer()`. ' +\n 'Use `COMPLIANCE_FIXTURES` directly and seed via your own integration path.'\n );\n}\n\nexport {\n createTestAuthorizationServer,\n type TestAuthorizationServer,\n type TestAuthorizationServerOptions,\n type IssueTokenOptions,\n} from './test-authorization-server';\n\nfunction isStateStore(value: unknown): value is AdcpStateStore {\n return (\n value != null &&\n typeof value === 'object' &&\n typeof (value as { put?: unknown }).put === 'function' &&\n typeof (value as { get?: unknown }).get === 'function' &&\n typeof (value as { list?: unknown }).list === 'function'\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
import { createServer } from "node:http";
|
|
8
2
|
import { SignJWT, calculateJwkThumbprint, exportJWK, generateKeyPair } from "jose";
|
|
9
3
|
const TOKEN_PATH = "/token";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/compliance-fixtures/test-authorization-server.ts"],"sourcesContent":["/**\n * In-process test authorization server for closed-loop compliance runs.\n *\n * Pairs with {@link seedComplianceFixtures} and `runAgainstLocalAgent` to\n * let sellers grade `security_baseline`, `signed-requests`, and any other\n * storyboard that needs real OAuth 2.0 tokens without reaching an\n * external IdP.\n *\n * What it exposes:\n * - `/.well-known/oauth-authorization-server` — RFC 8414 metadata\n * - `/.well-known/jwks.json` — JWKS with the AS public key\n * - `/token` — client_credentials token endpoint (always issues; this is\n * a fixture, not a real IdP)\n *\n * What the caller gets back:\n * - `issuer` — set on the token `iss` and in PRM `authorization_servers`\n * - `jwksUri` — point `verifyBearer({ jwksUri })` at this\n * - `issueToken()` — mint a JWT for any audience / scope / subject\n * - `close()` — tear down the HTTP listener (idempotent)\n *\n * Uses RS256 by default. HS* algorithms are refused — they would fail\n * `verifyBearer`'s asymmetric-only allowlist and teach sellers the wrong\n * setup.\n */\n\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport type { AddressInfo } from 'node:net';\nimport { SignJWT, calculateJwkThumbprint, exportJWK, generateKeyPair, type JWK } from 'jose';\n\nexport interface TestAuthorizationServerOptions {\n /** Bind host. Defaults to `127.0.0.1`. */\n host?: string;\n /** Bind port. `0` (default) lets the kernel assign one. */\n port?: number;\n /**\n * Canonical issuer URL to advertise in metadata and on issued JWTs.\n * Defaults to `http://<host>:<port>` once the listener is bound.\n *\n * Set this when fronting the AS behind a reverse proxy or tunnel so the\n * metadata and `iss` claim match the URL clients actually see.\n */\n issuer?: string;\n /**\n * JWT signing algorithm. Defaults to `RS256`. `ES256` is accepted for\n * fixtures that must mirror an ES-keyed production IdP.\n */\n algorithm?: 'RS256' | 'ES256';\n /**\n * Pre-seed subject → default-claims pairs so `issueToken({ sub })` picks\n * up the canonical identity without the caller repeating claim bodies.\n * Storyboard runners typically seed one entry per fixture brand_domain.\n */\n subjects?: Record<string, Record<string, unknown>>;\n /** Default token lifetime in seconds. Defaults to 3600. */\n tokenLifetimeSeconds?: number;\n}\n\nexport interface IssueTokenOptions {\n /**\n * Token subject. When this matches a preseeded subject the AS merges\n * the preseed's claims into the token (caller claims still win).\n */\n sub: string;\n /** RFC 8707 audience. Typically the agent's canonical publicUrl. */\n aud: string | string[];\n /** Scopes (encoded as RFC 8693 `scope`). */\n scope?: string | string[];\n /** Extra arbitrary claims merged on top of subject defaults. */\n claims?: Record<string, unknown>;\n /** Override the default token lifetime for this mint. */\n expiresInSeconds?: number;\n}\n\nexport interface TestAuthorizationServer {\n /** Base URL of the running AS (origin only, no path). */\n readonly baseUrl: string;\n /** Canonical issuer URL — matches the `iss` claim on issued tokens. */\n readonly issuer: string;\n /** RFC 8414 metadata URL. */\n readonly metadataUrl: string;\n /** JWKS URL — pass this to `verifyBearer({ jwksUri })`. */\n readonly jwksUri: string;\n /** Token endpoint URL — POST client_credentials here. */\n readonly tokenEndpoint: string;\n /** Mint a JWT. Returns the compact JWS string. */\n issueToken(options: IssueTokenOptions): Promise<string>;\n /** Stop the listener. Idempotent. */\n close(): Promise<void>;\n}\n\nconst TOKEN_PATH = '/token';\nconst JWKS_PATH = '/.well-known/jwks.json';\nconst METADATA_PATH = '/.well-known/oauth-authorization-server';\n\n/**\n * Start an in-process test authorization server. Safe to mount many\n * times in the same process; each call binds a fresh ephemeral port.\n */\nexport async function createTestAuthorizationServer(\n options: TestAuthorizationServerOptions = {}\n): Promise<TestAuthorizationServer> {\n const host = options.host ?? '127.0.0.1';\n const algorithm = options.algorithm ?? 'RS256';\n const tokenLifetimeSeconds = options.tokenLifetimeSeconds ?? 3600;\n const subjects: Record<string, Record<string, unknown>> = { ...(options.subjects ?? {}) };\n\n if (options.issuer && !/^https?:\\/\\//.test(options.issuer)) {\n throw new Error(`createTestAuthorizationServer: issuer must be http(s); got ${options.issuer}`);\n }\n\n const { publicKey, privateKey } = await generateKeyPair(algorithm, { extractable: true });\n const publicJwk = await exportJWK(publicKey);\n const kid = await calculateJwkThumbprint(publicJwk);\n publicJwk.kid = kid;\n publicJwk.alg = algorithm;\n publicJwk.use = 'sig';\n\n const state = {\n issuer: options.issuer?.replace(/\\/$/, '') ?? '',\n };\n\n const httpServer = createServer((req, res) => {\n handleRequest(req, res, state.issuer, publicJwk, async opts => mintToken(opts));\n });\n\n await new Promise<void>((resolve, reject) => {\n const onError = (err: Error) => reject(err);\n httpServer.once('error', onError);\n httpServer.listen(options.port ?? 0, host, () => {\n httpServer.off('error', onError);\n resolve();\n });\n });\n\n const bound = httpServer.address() as AddressInfo;\n const boundBase = `http://${formatHost(bound.address)}:${bound.port}`;\n if (!state.issuer) state.issuer = boundBase;\n\n async function mintToken(opts: IssueTokenOptions): Promise<string> {\n const preset = subjects[opts.sub] ?? {};\n const mergedClaims = { ...preset, ...(opts.claims ?? {}) };\n const scopeValue = Array.isArray(opts.scope) ? opts.scope.join(' ') : opts.scope;\n const now = Math.floor(Date.now() / 1000);\n const exp = now + (opts.expiresInSeconds ?? tokenLifetimeSeconds);\n return new SignJWT({\n ...mergedClaims,\n ...(scopeValue ? { scope: scopeValue } : {}),\n })\n .setProtectedHeader({ alg: algorithm, kid, typ: 'JWT' })\n .setSubject(opts.sub)\n .setIssuer(state.issuer)\n .setAudience(opts.aud)\n .setIssuedAt(now)\n .setExpirationTime(exp)\n .sign(privateKey);\n }\n\n return {\n baseUrl: boundBase,\n get issuer() {\n return state.issuer;\n },\n get metadataUrl() {\n return `${boundBase}${METADATA_PATH}`;\n },\n get jwksUri() {\n return `${boundBase}${JWKS_PATH}`;\n },\n get tokenEndpoint() {\n return `${boundBase}${TOKEN_PATH}`;\n },\n issueToken: mintToken,\n close: () => closeServer(httpServer),\n };\n}\n\n// ────────────────────────────────────────────────────────────\n// HTTP handlers\n// ────────────────────────────────────────────────────────────\n\nfunction handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n issuer: string,\n publicJwk: JWK,\n issueToken: (opts: IssueTokenOptions) => Promise<string>\n): void {\n const { pathname } = new URL(req.url || '', 'http://localhost');\n\n if (req.method === 'GET' && pathname === METADATA_PATH) {\n respondJson(res, 200, buildMetadata(issuer));\n return;\n }\n if (req.method === 'GET' && pathname === JWKS_PATH) {\n respondJson(res, 200, { keys: [publicJwk] });\n return;\n }\n if (req.method === 'POST' && pathname === TOKEN_PATH) {\n handleTokenEndpoint(req, res, issueToken).catch(err => {\n console.error('[adcp/test-authorization-server] token endpoint error:', err);\n if (!res.headersSent) respondJson(res, 500, { error: 'server_error' });\n });\n return;\n }\n\n res.statusCode = 404;\n res.end();\n}\n\nfunction buildMetadata(issuer: string): Record<string, unknown> {\n return {\n issuer,\n token_endpoint: `${issuer}${TOKEN_PATH}`,\n jwks_uri: `${issuer}${JWKS_PATH}`,\n grant_types_supported: ['client_credentials'],\n token_endpoint_auth_methods_supported: ['none', 'client_secret_basic', 'client_secret_post'],\n response_types_supported: ['token'],\n scopes_supported: ['adcp:read', 'adcp:write'],\n };\n}\n\nasync function handleTokenEndpoint(\n req: IncomingMessage,\n res: ServerResponse,\n issueToken: (opts: IssueTokenOptions) => Promise<string>\n): Promise<void> {\n const rawBody = await readBody(req);\n const form = parseFormOrJson(rawBody, req.headers['content-type']);\n\n const grantType = form.get('grant_type');\n if (grantType !== 'client_credentials') {\n respondJson(res, 400, {\n error: 'unsupported_grant_type',\n error_description: `Only client_credentials supported in the test AS; got ${grantType ?? '(none)'}`,\n });\n return;\n }\n const audience = form.get('resource') ?? form.get('audience');\n if (!audience) {\n respondJson(res, 400, {\n error: 'invalid_request',\n error_description: 'Missing `resource` (RFC 8707) or `audience` form parameter.',\n });\n return;\n }\n // Accept either form-posted `client_id` or HTTP Basic auth. The test AS\n // does not enforce a client registry — it issues for any caller.\n const clientId = form.get('client_id') ?? extractBasicAuthUsername(req.headers.authorization);\n const sub = clientId ?? 'test-client';\n const scope = form.get('scope') ?? undefined;\n\n const token = await issueToken({\n sub,\n aud: audience,\n scope,\n });\n respondJson(res, 200, {\n access_token: token,\n token_type: 'Bearer',\n expires_in: 3600,\n ...(scope ? { scope } : {}),\n });\n}\n\nfunction respondJson(res: ServerResponse, status: number, body: unknown): void {\n res.statusCode = status;\n res.setHeader('content-type', 'application/json');\n res.setHeader('cache-control', 'no-store');\n res.end(JSON.stringify(body));\n}\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n const MAX = 65_536;\n req.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX) {\n reject(new Error('token endpoint body exceeded 64 KiB'));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n req.on('error', reject);\n });\n}\n\nfunction parseFormOrJson(raw: string, contentType: string | string[] | undefined): Map<string, string> {\n const out = new Map<string, string>();\n if (raw.length === 0) return out;\n const ct = Array.isArray(contentType) ? contentType[0] : contentType;\n const looksJson = ct && /json/i.test(ct);\n if (looksJson) {\n try {\n const obj = JSON.parse(raw) as Record<string, unknown>;\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === 'string') out.set(k, v);\n }\n return out;\n } catch {\n return out;\n }\n }\n const params = new URLSearchParams(raw);\n for (const [k, v] of params.entries()) out.set(k, v);\n return out;\n}\n\nfunction extractBasicAuthUsername(auth: string | string[] | undefined): string | undefined {\n const header = Array.isArray(auth) ? auth[0] : auth;\n if (!header || !/^basic\\s+/i.test(header)) return undefined;\n const b64 = header.replace(/^basic\\s+/i, '').trim();\n try {\n const decoded = Buffer.from(b64, 'base64').toString('utf8');\n const colonIdx = decoded.indexOf(':');\n return colonIdx === -1 ? decoded : decoded.slice(0, colonIdx);\n } catch {\n return undefined;\n }\n}\n\nfunction formatHost(address: string): string {\n return address.includes(':') ? `[${address}]` : address;\n}\n\nfunction closeServer(server: Server): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n server.closeAllConnections?.();\n server.close(err => {\n if (err && (err as NodeJS.ErrnoException).code !== 'ERR_SERVER_NOT_RUNNING') reject(err);\n else resolve();\n });\n });\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/compliance-fixtures/test-authorization-server.ts"],"sourcesContent":["/**\n * In-process test authorization server for closed-loop compliance runs.\n *\n * Pairs with {@link seedComplianceFixtures} and `runAgainstLocalAgent` to\n * let sellers grade `security_baseline`, `signed-requests`, and any other\n * storyboard that needs real OAuth 2.0 tokens without reaching an\n * external IdP.\n *\n * What it exposes:\n * - `/.well-known/oauth-authorization-server` — RFC 8414 metadata\n * - `/.well-known/jwks.json` — JWKS with the AS public key\n * - `/token` — client_credentials token endpoint (always issues; this is\n * a fixture, not a real IdP)\n *\n * What the caller gets back:\n * - `issuer` — set on the token `iss` and in PRM `authorization_servers`\n * - `jwksUri` — point `verifyBearer({ jwksUri })` at this\n * - `issueToken()` — mint a JWT for any audience / scope / subject\n * - `close()` — tear down the HTTP listener (idempotent)\n *\n * Uses RS256 by default. HS* algorithms are refused — they would fail\n * `verifyBearer`'s asymmetric-only allowlist and teach sellers the wrong\n * setup.\n */\n\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport type { AddressInfo } from 'node:net';\nimport { SignJWT, calculateJwkThumbprint, exportJWK, generateKeyPair, type JWK } from 'jose';\n\nexport interface TestAuthorizationServerOptions {\n /** Bind host. Defaults to `127.0.0.1`. */\n host?: string;\n /** Bind port. `0` (default) lets the kernel assign one. */\n port?: number;\n /**\n * Canonical issuer URL to advertise in metadata and on issued JWTs.\n * Defaults to `http://<host>:<port>` once the listener is bound.\n *\n * Set this when fronting the AS behind a reverse proxy or tunnel so the\n * metadata and `iss` claim match the URL clients actually see.\n */\n issuer?: string;\n /**\n * JWT signing algorithm. Defaults to `RS256`. `ES256` is accepted for\n * fixtures that must mirror an ES-keyed production IdP.\n */\n algorithm?: 'RS256' | 'ES256';\n /**\n * Pre-seed subject → default-claims pairs so `issueToken({ sub })` picks\n * up the canonical identity without the caller repeating claim bodies.\n * Storyboard runners typically seed one entry per fixture brand_domain.\n */\n subjects?: Record<string, Record<string, unknown>>;\n /** Default token lifetime in seconds. Defaults to 3600. */\n tokenLifetimeSeconds?: number;\n}\n\nexport interface IssueTokenOptions {\n /**\n * Token subject. When this matches a preseeded subject the AS merges\n * the preseed's claims into the token (caller claims still win).\n */\n sub: string;\n /** RFC 8707 audience. Typically the agent's canonical publicUrl. */\n aud: string | string[];\n /** Scopes (encoded as RFC 8693 `scope`). */\n scope?: string | string[];\n /** Extra arbitrary claims merged on top of subject defaults. */\n claims?: Record<string, unknown>;\n /** Override the default token lifetime for this mint. */\n expiresInSeconds?: number;\n}\n\nexport interface TestAuthorizationServer {\n /** Base URL of the running AS (origin only, no path). */\n readonly baseUrl: string;\n /** Canonical issuer URL — matches the `iss` claim on issued tokens. */\n readonly issuer: string;\n /** RFC 8414 metadata URL. */\n readonly metadataUrl: string;\n /** JWKS URL — pass this to `verifyBearer({ jwksUri })`. */\n readonly jwksUri: string;\n /** Token endpoint URL — POST client_credentials here. */\n readonly tokenEndpoint: string;\n /** Mint a JWT. Returns the compact JWS string. */\n issueToken(options: IssueTokenOptions): Promise<string>;\n /** Stop the listener. Idempotent. */\n close(): Promise<void>;\n}\n\nconst TOKEN_PATH = '/token';\nconst JWKS_PATH = '/.well-known/jwks.json';\nconst METADATA_PATH = '/.well-known/oauth-authorization-server';\n\n/**\n * Start an in-process test authorization server. Safe to mount many\n * times in the same process; each call binds a fresh ephemeral port.\n */\nexport async function createTestAuthorizationServer(\n options: TestAuthorizationServerOptions = {}\n): Promise<TestAuthorizationServer> {\n const host = options.host ?? '127.0.0.1';\n const algorithm = options.algorithm ?? 'RS256';\n const tokenLifetimeSeconds = options.tokenLifetimeSeconds ?? 3600;\n const subjects: Record<string, Record<string, unknown>> = { ...(options.subjects ?? {}) };\n\n if (options.issuer && !/^https?:\\/\\//.test(options.issuer)) {\n throw new Error(`createTestAuthorizationServer: issuer must be http(s); got ${options.issuer}`);\n }\n\n const { publicKey, privateKey } = await generateKeyPair(algorithm, { extractable: true });\n const publicJwk = await exportJWK(publicKey);\n const kid = await calculateJwkThumbprint(publicJwk);\n publicJwk.kid = kid;\n publicJwk.alg = algorithm;\n publicJwk.use = 'sig';\n\n const state = {\n issuer: options.issuer?.replace(/\\/$/, '') ?? '',\n };\n\n const httpServer = createServer((req, res) => {\n handleRequest(req, res, state.issuer, publicJwk, async opts => mintToken(opts));\n });\n\n await new Promise<void>((resolve, reject) => {\n const onError = (err: Error) => reject(err);\n httpServer.once('error', onError);\n httpServer.listen(options.port ?? 0, host, () => {\n httpServer.off('error', onError);\n resolve();\n });\n });\n\n const bound = httpServer.address() as AddressInfo;\n const boundBase = `http://${formatHost(bound.address)}:${bound.port}`;\n if (!state.issuer) state.issuer = boundBase;\n\n async function mintToken(opts: IssueTokenOptions): Promise<string> {\n const preset = subjects[opts.sub] ?? {};\n const mergedClaims = { ...preset, ...(opts.claims ?? {}) };\n const scopeValue = Array.isArray(opts.scope) ? opts.scope.join(' ') : opts.scope;\n const now = Math.floor(Date.now() / 1000);\n const exp = now + (opts.expiresInSeconds ?? tokenLifetimeSeconds);\n return new SignJWT({\n ...mergedClaims,\n ...(scopeValue ? { scope: scopeValue } : {}),\n })\n .setProtectedHeader({ alg: algorithm, kid, typ: 'JWT' })\n .setSubject(opts.sub)\n .setIssuer(state.issuer)\n .setAudience(opts.aud)\n .setIssuedAt(now)\n .setExpirationTime(exp)\n .sign(privateKey);\n }\n\n return {\n baseUrl: boundBase,\n get issuer() {\n return state.issuer;\n },\n get metadataUrl() {\n return `${boundBase}${METADATA_PATH}`;\n },\n get jwksUri() {\n return `${boundBase}${JWKS_PATH}`;\n },\n get tokenEndpoint() {\n return `${boundBase}${TOKEN_PATH}`;\n },\n issueToken: mintToken,\n close: () => closeServer(httpServer),\n };\n}\n\n// ────────────────────────────────────────────────────────────\n// HTTP handlers\n// ────────────────────────────────────────────────────────────\n\nfunction handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n issuer: string,\n publicJwk: JWK,\n issueToken: (opts: IssueTokenOptions) => Promise<string>\n): void {\n const { pathname } = new URL(req.url || '', 'http://localhost');\n\n if (req.method === 'GET' && pathname === METADATA_PATH) {\n respondJson(res, 200, buildMetadata(issuer));\n return;\n }\n if (req.method === 'GET' && pathname === JWKS_PATH) {\n respondJson(res, 200, { keys: [publicJwk] });\n return;\n }\n if (req.method === 'POST' && pathname === TOKEN_PATH) {\n handleTokenEndpoint(req, res, issueToken).catch(err => {\n console.error('[adcp/test-authorization-server] token endpoint error:', err);\n if (!res.headersSent) respondJson(res, 500, { error: 'server_error' });\n });\n return;\n }\n\n res.statusCode = 404;\n res.end();\n}\n\nfunction buildMetadata(issuer: string): Record<string, unknown> {\n return {\n issuer,\n token_endpoint: `${issuer}${TOKEN_PATH}`,\n jwks_uri: `${issuer}${JWKS_PATH}`,\n grant_types_supported: ['client_credentials'],\n token_endpoint_auth_methods_supported: ['none', 'client_secret_basic', 'client_secret_post'],\n response_types_supported: ['token'],\n scopes_supported: ['adcp:read', 'adcp:write'],\n };\n}\n\nasync function handleTokenEndpoint(\n req: IncomingMessage,\n res: ServerResponse,\n issueToken: (opts: IssueTokenOptions) => Promise<string>\n): Promise<void> {\n const rawBody = await readBody(req);\n const form = parseFormOrJson(rawBody, req.headers['content-type']);\n\n const grantType = form.get('grant_type');\n if (grantType !== 'client_credentials') {\n respondJson(res, 400, {\n error: 'unsupported_grant_type',\n error_description: `Only client_credentials supported in the test AS; got ${grantType ?? '(none)'}`,\n });\n return;\n }\n const audience = form.get('resource') ?? form.get('audience');\n if (!audience) {\n respondJson(res, 400, {\n error: 'invalid_request',\n error_description: 'Missing `resource` (RFC 8707) or `audience` form parameter.',\n });\n return;\n }\n // Accept either form-posted `client_id` or HTTP Basic auth. The test AS\n // does not enforce a client registry — it issues for any caller.\n const clientId = form.get('client_id') ?? extractBasicAuthUsername(req.headers.authorization);\n const sub = clientId ?? 'test-client';\n const scope = form.get('scope') ?? undefined;\n\n const token = await issueToken({\n sub,\n aud: audience,\n scope,\n });\n respondJson(res, 200, {\n access_token: token,\n token_type: 'Bearer',\n expires_in: 3600,\n ...(scope ? { scope } : {}),\n });\n}\n\nfunction respondJson(res: ServerResponse, status: number, body: unknown): void {\n res.statusCode = status;\n res.setHeader('content-type', 'application/json');\n res.setHeader('cache-control', 'no-store');\n res.end(JSON.stringify(body));\n}\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n const MAX = 65_536;\n req.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX) {\n reject(new Error('token endpoint body exceeded 64 KiB'));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n req.on('error', reject);\n });\n}\n\nfunction parseFormOrJson(raw: string, contentType: string | string[] | undefined): Map<string, string> {\n const out = new Map<string, string>();\n if (raw.length === 0) return out;\n const ct = Array.isArray(contentType) ? contentType[0] : contentType;\n const looksJson = ct && /json/i.test(ct);\n if (looksJson) {\n try {\n const obj = JSON.parse(raw) as Record<string, unknown>;\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === 'string') out.set(k, v);\n }\n return out;\n } catch {\n return out;\n }\n }\n const params = new URLSearchParams(raw);\n for (const [k, v] of params.entries()) out.set(k, v);\n return out;\n}\n\nfunction extractBasicAuthUsername(auth: string | string[] | undefined): string | undefined {\n const header = Array.isArray(auth) ? auth[0] : auth;\n if (!header || !/^basic\\s+/i.test(header)) return undefined;\n const b64 = header.replace(/^basic\\s+/i, '').trim();\n try {\n const decoded = Buffer.from(b64, 'base64').toString('utf8');\n const colonIdx = decoded.indexOf(':');\n return colonIdx === -1 ? decoded : decoded.slice(0, colonIdx);\n } catch {\n return undefined;\n }\n}\n\nfunction formatHost(address: string): string {\n return address.includes(':') ? `[${address}]` : address;\n}\n\nfunction closeServer(server: Server): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n server.closeAllConnections?.();\n server.close(err => {\n if (err && (err as NodeJS.ErrnoException).code !== 'ERR_SERVER_NOT_RUNNING') reject(err);\n else resolve();\n });\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
import { runConformance } from "./runConformance.mjs";
|
|
8
2
|
import { runWebhookConformance } from "./webhook.mjs";
|
|
9
3
|
import { seedFixtures } from "./seeder.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/conformance/index.ts"],"sourcesContent":["/**\n * AdCP conformance fuzzer.\n *\n * Property-based testing against an agent's published JSON schemas.\n * Import from `@adcp/sdk/conformance` — kept off the runtime-client\n * path so `fast-check` and the schema bundle only load when fuzzing.\n *\n * ```ts\n * import { runConformance } from '@adcp/sdk/conformance';\n *\n * const report = await runConformance('https://agent.example.com', {\n * seed: 42,\n * tools: ['get_products', 'get_signals'],\n * });\n * if (report.totalFailures > 0) {\n * console.error(JSON.stringify(report.failures, null, 2));\n * process.exit(1);\n * }\n * ```\n */\n\nexport { runConformance } from './runConformance';\nexport { runWebhookConformance } from './webhook';\nexport { seedFixtures } from './seeder';\nexport type { SeedOptions, SeedResult, SeederName, SeedWarning } from './seeder';\nexport type { ConformanceSchemaOptions } from './schemaLoader';\nexport {\n STATELESS_TIER_TOOLS,\n REFERENTIAL_STATELESS_TOOLS,\n UPDATE_TIER_TOOLS,\n DEFAULT_TOOLS,\n DEFAULT_TOOLS_WITH_UPDATES,\n} from './types';\nexport type {\n ConformanceFailure,\n ConformanceFixtures,\n ConformanceReport,\n ConformanceToolName,\n ConformanceToolStats,\n OracleVerdict,\n RunConformanceOptions,\n RunWebhookConformanceOptions,\n SkipReason,\n WebhookConformanceCase,\n WebhookConformanceReport,\n WebhookConformanceSigningOptions,\n WebhookConformanceVerdict,\n} from './types';\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/conformance/index.ts"],"sourcesContent":["/**\n * AdCP conformance fuzzer.\n *\n * Property-based testing against an agent's published JSON schemas.\n * Import from `@adcp/sdk/conformance` — kept off the runtime-client\n * path so `fast-check` and the schema bundle only load when fuzzing.\n *\n * ```ts\n * import { runConformance } from '@adcp/sdk/conformance';\n *\n * const report = await runConformance('https://agent.example.com', {\n * seed: 42,\n * tools: ['get_products', 'get_signals'],\n * });\n * if (report.totalFailures > 0) {\n * console.error(JSON.stringify(report.failures, null, 2));\n * process.exit(1);\n * }\n * ```\n */\n\nexport { runConformance } from './runConformance';\nexport { runWebhookConformance } from './webhook';\nexport { seedFixtures } from './seeder';\nexport type { SeedOptions, SeedResult, SeederName, SeedWarning } from './seeder';\nexport type { ConformanceSchemaOptions } from './schemaLoader';\nexport {\n STATELESS_TIER_TOOLS,\n REFERENTIAL_STATELESS_TOOLS,\n UPDATE_TIER_TOOLS,\n DEFAULT_TOOLS,\n DEFAULT_TOOLS_WITH_UPDATES,\n} from './types';\nexport type {\n ConformanceFailure,\n ConformanceFixtures,\n ConformanceReport,\n ConformanceToolName,\n ConformanceToolStats,\n OracleVerdict,\n RunConformanceOptions,\n RunWebhookConformanceOptions,\n SkipReason,\n WebhookConformanceCase,\n WebhookConformanceReport,\n WebhookConformanceSigningOptions,\n WebhookConformanceVerdict,\n} from './types';\n"],"mappings":"AAqBA,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAG7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","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 { randomUUID } from "node:crypto";
|
|
8
2
|
import { withRawResponseCapture } from "../../protocols/rawResponseCapture.mjs";
|
|
9
3
|
import { compareProbes } from "./uniformErrorComparator.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/conformance/invariants/uniformError.ts"],"sourcesContent":["// Uniform error response invariant (adcp spec § error-handling).\n//\n// The spec MUSTs that a seller returns byte-equivalent responses for\n// \"the id exists but the caller lacks access\" vs \"the id does not\n// exist\" — through every observable channel (error code/message/field/\n// details, HTTP status, A2A task state / MCP isError, response headers,\n// latency distribution). Distinguishing the two leaks cross-tenant\n// existence information.\n//\n// This invariant exercises the MUST with a paired probe: two requests\n// to the same tool, compared byte-for-byte.\n//\n// Pairing modes:\n// - baseline: two fresh UUIDs, single auth token. Catches id-echo\n// leaks, header divergence, and grossly different latency. Does\n// not catch cross-tenant leaks — both ids are impossible, so the\n// \"inaccessible vs unknown\" branch never fires.\n// - cross-tenant: one seeded id owned by tenant A plus one fresh\n// UUID, both probed as tenant B. Catches the full MUST.\n//\n// Tool coverage is keyed by TOOL_ID_CONFIG below. A tool must expose\n// a single scalar \"lookup id\" field and have a matching seeder before\n// it can be probed.\n\nimport { AgentClient } from '../../core/AgentClient';\nimport { randomUUID } from 'node:crypto';\nimport { withRawResponseCapture, type RawHttpCapture } from '../../protocols/rawResponseCapture';\nimport type { ConformanceFixtures, ConformanceToolName } from '../types';\nimport { compareProbes, type ProbeComparisonResult } from './uniformErrorComparator';\n\nexport type UniformErrorVerdict = 'pass' | 'fail' | 'skipped';\n\nexport interface UniformErrorReport {\n tool: ConformanceToolName;\n /** Which pairing actually ran. */\n mode: 'baseline' | 'cross-tenant';\n verdict: UniformErrorVerdict;\n /** Populated on verdict === 'skipped'. */\n skipReason?: string;\n /** Populated on verdict !== 'skipped'. */\n differences?: string[];\n /** Probe summaries for diagnostics. Sanitized via `summarizeCapture`. */\n probes?: {\n inaccessibleOrRandomA: ProbeSummary;\n impossibleOrRandomB: ProbeSummary;\n };\n}\n\nexport interface ProbeSummary {\n /** Label describing what kind of id was probed. */\n label: 'cross-tenant' | 'impossible' | 'random-a' | 'random-b';\n status: number | null;\n headers: Record<string, string>;\n body: string;\n latencyMs: number;\n /** Whether the capture body was truncated. */\n bodyTruncated: boolean;\n}\n\n/**\n * Per-tool configuration for the invariant. Each tool that can be\n * probed declares:\n * - the single id field to mutate\n * - the fixture key that holds a seeded id (for cross-tenant mode)\n * - a minimal request builder given the id\n *\n * Extending coverage to more tools is additive — populate a new entry.\n */\ninterface ToolIdConfig {\n idField: string;\n /**\n * Fixture pool that holds a seeded \"accessible to tenant A\" id for\n * cross-tenant mode. When omitted, cross-tenant mode is unavailable\n * for this tool — baseline is the only mode. Useful for tools whose\n * ids don't come from a seeder (catalog-style lookups, provider-\n * owned signals, etc.).\n */\n fixtureKey?: keyof ConformanceFixtures;\n buildRequest: (id: string) => Record<string, unknown>;\n}\n\nconst TOOL_ID_CONFIG: Partial<Record<ConformanceToolName, ToolIdConfig>> = {\n get_property_list: {\n idField: 'list_id',\n fixtureKey: 'list_ids',\n buildRequest: id => ({ list_id: id }),\n },\n get_content_standards: {\n idField: 'standards_id',\n fixtureKey: 'standards_ids',\n buildRequest: id => ({ standards_id: id }),\n },\n get_media_buy_delivery: {\n idField: 'media_buy_id',\n fixtureKey: 'media_buy_ids',\n buildRequest: id => {\n // Spec-min request: one buy id + a date range wide enough to avoid\n // per-seller reporting-window rejection. Dates are arbitrary — the\n // resolution happens before access-check per the spec, so the\n // response must be byte-equivalent regardless of window.\n const now = new Date();\n const start = new Date(now.getTime() - 7 * 86400_000).toISOString().slice(0, 10);\n const end = new Date(now.getTime() + 7 * 86400_000).toISOString().slice(0, 10);\n return { media_buy_ids: [id], start_date: start, end_date: end };\n },\n },\n get_creative_delivery: {\n idField: 'creative_id',\n fixtureKey: 'creative_ids',\n buildRequest: id => {\n const now = new Date();\n const start = new Date(now.getTime() - 7 * 86400_000).toISOString().slice(0, 10);\n const end = new Date(now.getTime() + 7 * 86400_000).toISOString().slice(0, 10);\n return { creative_ids: [id], start_date: start, end_date: end };\n },\n },\n tasks_get: {\n idField: 'task_id',\n fixtureKey: 'task_ids',\n buildRequest: id => ({ task_id: id }),\n },\n get_signals: {\n idField: 'signal_ids',\n // No seeder for signals today (catalog signals are provider-\n // controlled, not agent-created). Baseline-only: two fresh UUIDs\n // wrapped in a SignalID shape, probed under the single caller\n // token. Cross-tenant mode becomes available when the signals\n // protocol grows a create/sync path and a seeder produces ids.\n buildRequest: id => ({\n signal_ids: [{ source: 'catalog', data_provider_domain: 'conformance.example', id }],\n }),\n },\n};\n\n/** Tools eligible for the uniform-error probe. Used by the runner wiring. */\nexport function toolsEligibleForUniformError(): ConformanceToolName[] {\n return Object.keys(TOOL_ID_CONFIG) as ConformanceToolName[];\n}\n\nexport interface ProbeOptions {\n /** Agent client that probes with the \"caller\" credentials (tenant B in cross-tenant mode). */\n prober: AgentClient;\n /** Fixtures accumulated so far — drawn from for cross-tenant mode. */\n fixtures: ConformanceFixtures;\n /** Whether a distinct cross-tenant token was configured. When false, mode is 'baseline'. */\n crossTenantConfigured: boolean;\n /**\n * Cap individual probe body size in the capture. Defaults to the\n * rawResponseCapture default. Not usually worth overriding.\n */\n maxBodyBytes?: number;\n}\n\nexport async function runUniformErrorInvariant(\n tool: ConformanceToolName,\n options: ProbeOptions\n): Promise<UniformErrorReport> {\n const config = TOOL_ID_CONFIG[tool];\n if (!config) {\n return {\n tool,\n mode: options.crossTenantConfigured ? 'cross-tenant' : 'baseline',\n verdict: 'skipped',\n skipReason: 'tool not in TOOL_ID_CONFIG',\n };\n }\n\n // Resolve the pair of ids under probe.\n //\n // Cross-tenant mode needs a seeded id (tenant A owns the resource;\n // tenant B is probing it — that's the \"exists but inaccessible\" leg).\n // Missing seeded id (or a tool with no fixtureKey at all, like\n // get_signals) → fall back to baseline rather than skipping; the\n // baseline still catches id-echo and header-divergence leaks.\n const seededPool = config.fixtureKey ? (options.fixtures[config.fixtureKey] ?? []) : [];\n const seededId = seededPool[0];\n const mode: UniformErrorReport['mode'] = options.crossTenantConfigured && seededId ? 'cross-tenant' : 'baseline';\n\n const idA = mode === 'cross-tenant' ? (seededId as string) : randomUUID();\n const idB = randomUUID();\n const labelA: ProbeSummary['label'] = mode === 'cross-tenant' ? 'cross-tenant' : 'random-a';\n const labelB: ProbeSummary['label'] = mode === 'cross-tenant' ? 'impossible' : 'random-b';\n\n const captureOpts = { maxBodyBytes: options.maxBodyBytes };\n\n const probeA = await capturedProbe(options.prober, tool, config.buildRequest(idA), captureOpts);\n const probeB = await capturedProbe(options.prober, tool, config.buildRequest(idB), captureOpts);\n\n if (!probeA.capture || !probeB.capture) {\n // One side didn't produce a capture — the underlying transport\n // surfaced an error before we could observe the response (e.g.,\n // the SDK threw an AuthenticationRequiredError). Report the root\n // cause so the operator knows why the invariant skipped.\n const reason = probeA.error ?? probeB.error ?? 'no capture observed';\n return {\n tool,\n mode,\n verdict: 'skipped',\n skipReason: `probe did not produce a raw capture (${reason})`,\n };\n }\n\n const comparison = compareProbes(probeA.capture, probeB.capture);\n\n return {\n tool,\n mode,\n verdict: comparison.equivalent ? 'pass' : 'fail',\n differences: comparison.differences,\n probes: {\n inaccessibleOrRandomA: summarizeCapture(probeA.capture, labelA),\n impossibleOrRandomB: summarizeCapture(probeB.capture, labelB),\n },\n };\n}\n\ninterface ProbeOutcome {\n capture?: RawHttpCapture;\n /** Error message when executeTask threw before producing a capture. */\n error?: string;\n}\n\n/**\n * Execute a probe inside a capture context and return the tool-call\n * response. Filters captures to POST — MCP's tool call and A2A's\n * `sendMessage` are both POSTs, while A2A's `/.well-known/agent.json`\n * discovery (issued on a fresh client) is a GET that we must not\n * confuse with the tool response.\n */\nasync function capturedProbe(\n agent: AgentClient,\n tool: ConformanceToolName,\n request: Record<string, unknown>,\n options: { maxBodyBytes?: number }\n): Promise<ProbeOutcome> {\n try {\n const { captures } = await withRawResponseCapture(async () => {\n await agent.executeTask(tool, request);\n }, options);\n const toolCallCapture = lastPostCapture(captures);\n if (!toolCallCapture) {\n return { error: 'captured only non-POST traffic' };\n }\n return { capture: toolCallCapture };\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction lastPostCapture(captures: readonly RawHttpCapture[]): RawHttpCapture | undefined {\n for (let i = captures.length - 1; i >= 0; i--) {\n const cap = captures[i];\n if (cap && cap.method === 'POST') return cap;\n }\n return undefined;\n}\n\nfunction summarizeCapture(cap: RawHttpCapture, label: ProbeSummary['label']): ProbeSummary {\n return {\n label,\n status: cap.status,\n headers: cap.headers,\n body: cap.body,\n latencyMs: cap.latencyMs,\n bodyTruncated: cap.bodyTruncated,\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/conformance/invariants/uniformError.ts"],"sourcesContent":["// Uniform error response invariant (adcp spec § error-handling).\n//\n// The spec MUSTs that a seller returns byte-equivalent responses for\n// \"the id exists but the caller lacks access\" vs \"the id does not\n// exist\" — through every observable channel (error code/message/field/\n// details, HTTP status, A2A task state / MCP isError, response headers,\n// latency distribution). Distinguishing the two leaks cross-tenant\n// existence information.\n//\n// This invariant exercises the MUST with a paired probe: two requests\n// to the same tool, compared byte-for-byte.\n//\n// Pairing modes:\n// - baseline: two fresh UUIDs, single auth token. Catches id-echo\n// leaks, header divergence, and grossly different latency. Does\n// not catch cross-tenant leaks — both ids are impossible, so the\n// \"inaccessible vs unknown\" branch never fires.\n// - cross-tenant: one seeded id owned by tenant A plus one fresh\n// UUID, both probed as tenant B. Catches the full MUST.\n//\n// Tool coverage is keyed by TOOL_ID_CONFIG below. A tool must expose\n// a single scalar \"lookup id\" field and have a matching seeder before\n// it can be probed.\n\nimport { AgentClient } from '../../core/AgentClient';\nimport { randomUUID } from 'node:crypto';\nimport { withRawResponseCapture, type RawHttpCapture } from '../../protocols/rawResponseCapture';\nimport type { ConformanceFixtures, ConformanceToolName } from '../types';\nimport { compareProbes, type ProbeComparisonResult } from './uniformErrorComparator';\n\nexport type UniformErrorVerdict = 'pass' | 'fail' | 'skipped';\n\nexport interface UniformErrorReport {\n tool: ConformanceToolName;\n /** Which pairing actually ran. */\n mode: 'baseline' | 'cross-tenant';\n verdict: UniformErrorVerdict;\n /** Populated on verdict === 'skipped'. */\n skipReason?: string;\n /** Populated on verdict !== 'skipped'. */\n differences?: string[];\n /** Probe summaries for diagnostics. Sanitized via `summarizeCapture`. */\n probes?: {\n inaccessibleOrRandomA: ProbeSummary;\n impossibleOrRandomB: ProbeSummary;\n };\n}\n\nexport interface ProbeSummary {\n /** Label describing what kind of id was probed. */\n label: 'cross-tenant' | 'impossible' | 'random-a' | 'random-b';\n status: number | null;\n headers: Record<string, string>;\n body: string;\n latencyMs: number;\n /** Whether the capture body was truncated. */\n bodyTruncated: boolean;\n}\n\n/**\n * Per-tool configuration for the invariant. Each tool that can be\n * probed declares:\n * - the single id field to mutate\n * - the fixture key that holds a seeded id (for cross-tenant mode)\n * - a minimal request builder given the id\n *\n * Extending coverage to more tools is additive — populate a new entry.\n */\ninterface ToolIdConfig {\n idField: string;\n /**\n * Fixture pool that holds a seeded \"accessible to tenant A\" id for\n * cross-tenant mode. When omitted, cross-tenant mode is unavailable\n * for this tool — baseline is the only mode. Useful for tools whose\n * ids don't come from a seeder (catalog-style lookups, provider-\n * owned signals, etc.).\n */\n fixtureKey?: keyof ConformanceFixtures;\n buildRequest: (id: string) => Record<string, unknown>;\n}\n\nconst TOOL_ID_CONFIG: Partial<Record<ConformanceToolName, ToolIdConfig>> = {\n get_property_list: {\n idField: 'list_id',\n fixtureKey: 'list_ids',\n buildRequest: id => ({ list_id: id }),\n },\n get_content_standards: {\n idField: 'standards_id',\n fixtureKey: 'standards_ids',\n buildRequest: id => ({ standards_id: id }),\n },\n get_media_buy_delivery: {\n idField: 'media_buy_id',\n fixtureKey: 'media_buy_ids',\n buildRequest: id => {\n // Spec-min request: one buy id + a date range wide enough to avoid\n // per-seller reporting-window rejection. Dates are arbitrary — the\n // resolution happens before access-check per the spec, so the\n // response must be byte-equivalent regardless of window.\n const now = new Date();\n const start = new Date(now.getTime() - 7 * 86400_000).toISOString().slice(0, 10);\n const end = new Date(now.getTime() + 7 * 86400_000).toISOString().slice(0, 10);\n return { media_buy_ids: [id], start_date: start, end_date: end };\n },\n },\n get_creative_delivery: {\n idField: 'creative_id',\n fixtureKey: 'creative_ids',\n buildRequest: id => {\n const now = new Date();\n const start = new Date(now.getTime() - 7 * 86400_000).toISOString().slice(0, 10);\n const end = new Date(now.getTime() + 7 * 86400_000).toISOString().slice(0, 10);\n return { creative_ids: [id], start_date: start, end_date: end };\n },\n },\n tasks_get: {\n idField: 'task_id',\n fixtureKey: 'task_ids',\n buildRequest: id => ({ task_id: id }),\n },\n get_signals: {\n idField: 'signal_ids',\n // No seeder for signals today (catalog signals are provider-\n // controlled, not agent-created). Baseline-only: two fresh UUIDs\n // wrapped in a SignalID shape, probed under the single caller\n // token. Cross-tenant mode becomes available when the signals\n // protocol grows a create/sync path and a seeder produces ids.\n buildRequest: id => ({\n signal_ids: [{ source: 'catalog', data_provider_domain: 'conformance.example', id }],\n }),\n },\n};\n\n/** Tools eligible for the uniform-error probe. Used by the runner wiring. */\nexport function toolsEligibleForUniformError(): ConformanceToolName[] {\n return Object.keys(TOOL_ID_CONFIG) as ConformanceToolName[];\n}\n\nexport interface ProbeOptions {\n /** Agent client that probes with the \"caller\" credentials (tenant B in cross-tenant mode). */\n prober: AgentClient;\n /** Fixtures accumulated so far — drawn from for cross-tenant mode. */\n fixtures: ConformanceFixtures;\n /** Whether a distinct cross-tenant token was configured. When false, mode is 'baseline'. */\n crossTenantConfigured: boolean;\n /**\n * Cap individual probe body size in the capture. Defaults to the\n * rawResponseCapture default. Not usually worth overriding.\n */\n maxBodyBytes?: number;\n}\n\nexport async function runUniformErrorInvariant(\n tool: ConformanceToolName,\n options: ProbeOptions\n): Promise<UniformErrorReport> {\n const config = TOOL_ID_CONFIG[tool];\n if (!config) {\n return {\n tool,\n mode: options.crossTenantConfigured ? 'cross-tenant' : 'baseline',\n verdict: 'skipped',\n skipReason: 'tool not in TOOL_ID_CONFIG',\n };\n }\n\n // Resolve the pair of ids under probe.\n //\n // Cross-tenant mode needs a seeded id (tenant A owns the resource;\n // tenant B is probing it — that's the \"exists but inaccessible\" leg).\n // Missing seeded id (or a tool with no fixtureKey at all, like\n // get_signals) → fall back to baseline rather than skipping; the\n // baseline still catches id-echo and header-divergence leaks.\n const seededPool = config.fixtureKey ? (options.fixtures[config.fixtureKey] ?? []) : [];\n const seededId = seededPool[0];\n const mode: UniformErrorReport['mode'] = options.crossTenantConfigured && seededId ? 'cross-tenant' : 'baseline';\n\n const idA = mode === 'cross-tenant' ? (seededId as string) : randomUUID();\n const idB = randomUUID();\n const labelA: ProbeSummary['label'] = mode === 'cross-tenant' ? 'cross-tenant' : 'random-a';\n const labelB: ProbeSummary['label'] = mode === 'cross-tenant' ? 'impossible' : 'random-b';\n\n const captureOpts = { maxBodyBytes: options.maxBodyBytes };\n\n const probeA = await capturedProbe(options.prober, tool, config.buildRequest(idA), captureOpts);\n const probeB = await capturedProbe(options.prober, tool, config.buildRequest(idB), captureOpts);\n\n if (!probeA.capture || !probeB.capture) {\n // One side didn't produce a capture — the underlying transport\n // surfaced an error before we could observe the response (e.g.,\n // the SDK threw an AuthenticationRequiredError). Report the root\n // cause so the operator knows why the invariant skipped.\n const reason = probeA.error ?? probeB.error ?? 'no capture observed';\n return {\n tool,\n mode,\n verdict: 'skipped',\n skipReason: `probe did not produce a raw capture (${reason})`,\n };\n }\n\n const comparison = compareProbes(probeA.capture, probeB.capture);\n\n return {\n tool,\n mode,\n verdict: comparison.equivalent ? 'pass' : 'fail',\n differences: comparison.differences,\n probes: {\n inaccessibleOrRandomA: summarizeCapture(probeA.capture, labelA),\n impossibleOrRandomB: summarizeCapture(probeB.capture, labelB),\n },\n };\n}\n\ninterface ProbeOutcome {\n capture?: RawHttpCapture;\n /** Error message when executeTask threw before producing a capture. */\n error?: string;\n}\n\n/**\n * Execute a probe inside a capture context and return the tool-call\n * response. Filters captures to POST — MCP's tool call and A2A's\n * `sendMessage` are both POSTs, while A2A's `/.well-known/agent.json`\n * discovery (issued on a fresh client) is a GET that we must not\n * confuse with the tool response.\n */\nasync function capturedProbe(\n agent: AgentClient,\n tool: ConformanceToolName,\n request: Record<string, unknown>,\n options: { maxBodyBytes?: number }\n): Promise<ProbeOutcome> {\n try {\n const { captures } = await withRawResponseCapture(async () => {\n await agent.executeTask(tool, request);\n }, options);\n const toolCallCapture = lastPostCapture(captures);\n if (!toolCallCapture) {\n return { error: 'captured only non-POST traffic' };\n }\n return { capture: toolCallCapture };\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction lastPostCapture(captures: readonly RawHttpCapture[]): RawHttpCapture | undefined {\n for (let i = captures.length - 1; i >= 0; i--) {\n const cap = captures[i];\n if (cap && cap.method === 'POST') return cap;\n }\n return undefined;\n}\n\nfunction summarizeCapture(cap: RawHttpCapture, label: ProbeSummary['label']): ProbeSummary {\n return {\n label,\n status: cap.status,\n headers: cap.headers,\n body: cap.body,\n latencyMs: cap.latencyMs,\n bodyTruncated: cap.bodyTruncated,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
const HEADER_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
8
2
|
// Timing / diagnostic
|
|
9
3
|
"date",
|