@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/utils/validate-user-agent.ts"],"sourcesContent":["/**\n * Validate a user-agent string for safe use in HTTP headers.\n * Rejects newlines (CRLF injection) and null bytes (header truncation).\n *\n * @throws {Error} if the value contains forbidden characters\n */\nexport function validateUserAgent(value: string): void {\n if (/[\\r\\n\\x00]/.test(value)) {\n throw new Error('userAgent must not contain newline or null characters');\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils/validate-user-agent.ts"],"sourcesContent":["/**\n * Validate a user-agent string for safe use in HTTP headers.\n * Rejects newlines (CRLF injection) and null bytes (header truncation).\n *\n * @throws {Error} if the value contains forbidden characters\n */\nexport function validateUserAgent(value: string): void {\n if (/[\\r\\n\\x00]/.test(value)) {\n throw new Error('userAgent must not contain newline or null characters');\n }\n}\n"],"mappings":"AAMO,SAAS,kBAAkB,OAAqB;AACrD,MAAI,aAAa,KAAK,KAAK,GAAG;AAC5B,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACF;","names":[]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
import { createHash } from "crypto";
|
|
8
2
|
import { ssrfSafeFetch, SsrfRefusedError } from "../../net/ssrf-fetch.mjs";
|
|
9
3
|
import { isInternalProbesAllowed } from "../../utils/probe-policy.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/v2/format-schema/fetch.ts"],"sourcesContent":["/**\n * Fetch + digest-verify a format_schema referenced from\n * `ProductFormatDeclaration.format_schema` (`{uri, digest}`).\n *\n * Implements the spec's normative fetch contract from\n * `product-format-declaration.json#format_schema`:\n *\n * - **Transport**: https only โ enforced by ssrfSafeFetch\n * (rejects http/file/data; rejects loopback, private, link-local,\n * CGNAT, and RFC 6761 special-use names; rejects cloud-metadata\n * endpoints; pins outbound to resolved IP to defeat DNS rebinding).\n * - **Redirects**: disabled โ ssrfSafeFetch uses `redirect: 'manual'`,\n * so HTTP 3xx returns the redirect response. Caller treats as a\n * hard fail.\n * - **Response size cap**: 1 MiB โ enforced by ssrfSafeFetch\n * `maxBodyBytes`. Over-cap rejects.\n * - **Timeout**: 5 seconds default; caller may override but spec\n * recommends โค5s.\n * - **Digest verification**: SHA-256 of response body MUST equal\n * `digest`. Mismatch is a hard fail.\n * - **Cache**: keyed by `uri@digest`; immutable.\n *\n * Higher-level helper:\n * - `createCanonicalReferenceResolver()` wraps this fetcher with\n * per-caller caching, `$ref` sandboxing, JSON Schema compilation,\n * and non-throwing structured statuses for both `format_schema` and\n * `platform_extensions` references.\n *\n * Out of scope for this low-level fetcher:\n * - Stronger transparency-log / signed-body verification โ tracked\n * separately in the spec; mirror-trust hardening is future work.\n */\n\nimport { createHash } from 'crypto';\nimport { ssrfSafeFetch, SsrfRefusedError } from '../../net/ssrf-fetch';\nimport { isInternalProbesAllowed } from '../../utils/probe-policy';\n\n/** Reference to a format schema, mirroring `platform-extension-ref.json`. */\nexport interface FormatSchemaRef {\n uri: string;\n /** `sha256:` prefix + 64 lowercase hex characters. */\n digest: string;\n}\n\n/**\n * Error codes from {@link fetchFormatSchema}. Mirror the spec's\n * normative failure modes so SDK callers can surface them on the\n * response `errors[]` array with consistent codes.\n */\nexport type FormatSchemaFetchErrorCode =\n /** URI/digest pair fails basic shape checks (non-https URI, malformed digest). */\n | 'invalid_ref'\n /** SSRF guard refused (private IP, loopback, link-local, scheme, ...). */\n | 'ssrf_refused'\n /** HTTP response was a redirect (3xx) โ auto-follow is disabled. */\n | 'redirect_blocked'\n /** Non-2xx HTTP status. */\n | 'http_error'\n /** Response body exceeded 1 MiB cap. */\n | 'body_too_large'\n /** Response body wasn't valid JSON. */\n | 'invalid_json'\n /** SHA-256 of body didn't match the supplied digest. */\n | 'digest_mismatch'\n /** Network/timeout failure. */\n | 'network_error';\n\nexport class FormatSchemaFetchError extends Error {\n readonly code: FormatSchemaFetchErrorCode;\n readonly uri: string;\n readonly digest?: string;\n readonly httpStatus?: number;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: FormatSchemaFetchErrorCode,\n message: string,\n meta: { uri: string; digest?: string; httpStatus?: number; details?: Record<string, unknown> }\n ) {\n super(message);\n this.name = 'FormatSchemaFetchError';\n this.code = code;\n this.uri = meta.uri;\n this.digest = meta.digest;\n this.httpStatus = meta.httpStatus;\n this.details = meta.details;\n }\n}\n\nexport interface FormatSchemaFetchResult {\n /** The parsed JSON schema document. */\n schema: Record<string, unknown>;\n /** Echo of the input ref (handy for downstream caching). */\n ref: FormatSchemaRef;\n /**\n * Whether the result was served from the in-process cache. Helpful\n * for telemetry; fresh fetches and cache hits both return successful\n * results.\n */\n fromCache: boolean;\n}\n\nexport interface FetchFormatSchemaOptions {\n /**\n * Fetch timeout in ms. Default 5_000 per spec recommendation\n * (\"SDKs SHOULD apply a fetch timeout โค5 seconds\").\n */\n timeoutMs?: number;\n /**\n * Hard cap on response body bytes. Default 1 MiB per spec. Lower this\n * for tight environments; do not raise above the spec ceiling.\n */\n maxBodyBytes?: number;\n /**\n * Caller-scoped test/dev opt-in for loopback/private HTTP fetches.\n * Production callers should leave this false. IMDS/link-local\n * metadata endpoints remain blocked by `ssrfSafeFetch`.\n */\n allowInternalReferences?: boolean;\n /**\n * Override the module-level cache. Useful when callers want\n * per-session caches or to disable caching entirely\n * (`{ get: () => undefined, set: () => {} }`).\n */\n cache?: FormatSchemaCache;\n}\n\n/** Pluggable cache interface โ defaults to an in-process Map. */\nexport interface FormatSchemaCache {\n get(key: string): FormatSchemaFetchResult | undefined;\n set(key: string, value: FormatSchemaFetchResult): void;\n}\n\nconst DEFAULT_TIMEOUT_MS = 5_000;\nconst DEFAULT_MAX_BODY_BYTES = 1024 * 1024;\nconst DIGEST_RE = /^sha256:[0-9a-f]{64}$/;\n\nfunction cloneJsonRecord<T extends Record<string, unknown>>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction cloneFetchResult(result: FormatSchemaFetchResult, fromCache: boolean): FormatSchemaFetchResult {\n return {\n schema: cloneJsonRecord(result.schema),\n ref: { ...result.ref },\n fromCache,\n };\n}\n\nfunction defaultCache(): FormatSchemaCache {\n const store = new Map<string, FormatSchemaFetchResult>();\n return {\n get: key => store.get(key),\n set: (key, value) => {\n store.set(key, cloneFetchResult(value, false));\n },\n };\n}\n\nlet moduleCache = defaultCache();\n\n/** Test hook: drop the module-level cache. */\nexport function _resetFormatSchemaCache(): void {\n moduleCache = defaultCache();\n}\n\n/**\n * Fetch and digest-verify a format_schema reference. Returns the parsed\n * schema on success; throws {@link FormatSchemaFetchError} on every\n * failure mode so callers can surface a normalized diagnostic.\n */\nexport async function fetchFormatSchema(\n ref: FormatSchemaRef,\n options: FetchFormatSchemaOptions = {}\n): Promise<FormatSchemaFetchResult> {\n if (!ref || typeof ref.uri !== 'string' || typeof ref.digest !== 'string') {\n throw new FormatSchemaFetchError('invalid_ref', 'format_schema ref must carry { uri, digest }', {\n uri: ref?.uri ?? '<missing>',\n });\n }\n // Production: HTTPS-only per spec. Loopback test runs (gated by\n // ADCP_ALLOW_INTERNAL_PROBES=1) may use `http://` against a 127.0.0.1\n // mock โ same opt-in pattern as the discovery layer.\n const allowHttp = options.allowInternalReferences === true || isInternalProbesAllowed();\n if (!ref.uri.startsWith('https://') && !(allowHttp && ref.uri.startsWith('http://'))) {\n throw new FormatSchemaFetchError('invalid_ref', 'format_schema.uri must use https:// (spec normative)', {\n uri: ref.uri,\n });\n }\n if (!DIGEST_RE.test(ref.digest)) {\n throw new FormatSchemaFetchError(\n 'invalid_ref',\n 'format_schema.digest must be `sha256:` + 64 lowercase hex characters',\n { uri: ref.uri, digest: ref.digest }\n );\n }\n\n const cache = options.cache ?? moduleCache;\n const cacheKey = `${ref.uri}@${ref.digest}`;\n const cached = cache.get(cacheKey);\n if (cached) {\n return cloneFetchResult(cached, true);\n }\n\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;\n\n let response;\n try {\n response = await ssrfSafeFetch(ref.uri, {\n method: 'GET',\n timeoutMs,\n maxBodyBytes,\n headers: {\n accept: 'application/schema+json, application/json',\n },\n // Internal-probes opt-in mirrors the discovery layer โ production\n // stays HTTPS+non-private; loopback tests opt in via env.\n allowPrivateIp: allowHttp,\n });\n } catch (err) {\n if (err instanceof SsrfRefusedError) {\n if (err.code === 'body_exceeds_limit') {\n throw new FormatSchemaFetchError('body_too_large', err.message, { uri: ref.uri, digest: ref.digest });\n }\n throw new FormatSchemaFetchError('ssrf_refused', `SSRF guard refused: ${err.message}`, {\n uri: ref.uri,\n digest: ref.digest,\n details: { code: err.code, hostname: err.hostname },\n });\n }\n const message = err instanceof Error ? err.message : String(err);\n // Distinguish over-cap from generic network errors so callers can\n // surface the spec's \"body_too_large is a hard fail\" semantics.\n if (/body too large|maxBodyBytes/i.test(message)) {\n throw new FormatSchemaFetchError('body_too_large', message, { uri: ref.uri, digest: ref.digest });\n }\n throw new FormatSchemaFetchError('network_error', message, { uri: ref.uri, digest: ref.digest });\n }\n\n // Spec: \"HTTP redirects MUST be disabled.\" ssrfSafeFetch uses\n // `redirect: 'manual'`, so 3xx returns the redirect response. Treat\n // as a hard fail per the spec.\n if (response.status >= 300 && response.status < 400) {\n throw new FormatSchemaFetchError(\n 'redirect_blocked',\n `HTTP redirect (${response.status}) โ auto-follow disabled per spec`,\n {\n uri: ref.uri,\n digest: ref.digest,\n httpStatus: response.status,\n }\n );\n }\n if (response.status < 200 || response.status >= 300) {\n throw new FormatSchemaFetchError('http_error', `HTTP ${response.status}`, {\n uri: ref.uri,\n digest: ref.digest,\n httpStatus: response.status,\n });\n }\n\n const bodyBytes = response.body;\n const actualDigest = `sha256:${createHash('sha256').update(bodyBytes).digest('hex')}`;\n if (actualDigest !== ref.digest) {\n throw new FormatSchemaFetchError(\n 'digest_mismatch',\n `digest mismatch: expected ${ref.digest}, got ${actualDigest}`,\n { uri: ref.uri, digest: ref.digest, details: { actualDigest } }\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(new TextDecoder('utf-8').decode(bodyBytes));\n } catch (err) {\n throw new FormatSchemaFetchError(\n 'invalid_json',\n `response body is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n { uri: ref.uri, digest: ref.digest }\n );\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new FormatSchemaFetchError(\n 'invalid_json',\n 'response body is not a JSON object (JSON Schema documents are objects)',\n { uri: ref.uri, digest: ref.digest }\n );\n }\n\n const result: FormatSchemaFetchResult = {\n schema: parsed as Record<string, unknown>,\n ref: { ...ref },\n fromCache: false,\n };\n cache.set(cacheKey, result);\n return cloneFetchResult(result, false);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/v2/format-schema/fetch.ts"],"sourcesContent":["/**\n * Fetch + digest-verify a format_schema referenced from\n * `ProductFormatDeclaration.format_schema` (`{uri, digest}`).\n *\n * Implements the spec's normative fetch contract from\n * `product-format-declaration.json#format_schema`:\n *\n * - **Transport**: https only โ enforced by ssrfSafeFetch\n * (rejects http/file/data; rejects loopback, private, link-local,\n * CGNAT, and RFC 6761 special-use names; rejects cloud-metadata\n * endpoints; pins outbound to resolved IP to defeat DNS rebinding).\n * - **Redirects**: disabled โ ssrfSafeFetch uses `redirect: 'manual'`,\n * so HTTP 3xx returns the redirect response. Caller treats as a\n * hard fail.\n * - **Response size cap**: 1 MiB โ enforced by ssrfSafeFetch\n * `maxBodyBytes`. Over-cap rejects.\n * - **Timeout**: 5 seconds default; caller may override but spec\n * recommends โค5s.\n * - **Digest verification**: SHA-256 of response body MUST equal\n * `digest`. Mismatch is a hard fail.\n * - **Cache**: keyed by `uri@digest`; immutable.\n *\n * Higher-level helper:\n * - `createCanonicalReferenceResolver()` wraps this fetcher with\n * per-caller caching, `$ref` sandboxing, JSON Schema compilation,\n * and non-throwing structured statuses for both `format_schema` and\n * `platform_extensions` references.\n *\n * Out of scope for this low-level fetcher:\n * - Stronger transparency-log / signed-body verification โ tracked\n * separately in the spec; mirror-trust hardening is future work.\n */\n\nimport { createHash } from 'crypto';\nimport { ssrfSafeFetch, SsrfRefusedError } from '../../net/ssrf-fetch';\nimport { isInternalProbesAllowed } from '../../utils/probe-policy';\n\n/** Reference to a format schema, mirroring `platform-extension-ref.json`. */\nexport interface FormatSchemaRef {\n uri: string;\n /** `sha256:` prefix + 64 lowercase hex characters. */\n digest: string;\n}\n\n/**\n * Error codes from {@link fetchFormatSchema}. Mirror the spec's\n * normative failure modes so SDK callers can surface them on the\n * response `errors[]` array with consistent codes.\n */\nexport type FormatSchemaFetchErrorCode =\n /** URI/digest pair fails basic shape checks (non-https URI, malformed digest). */\n | 'invalid_ref'\n /** SSRF guard refused (private IP, loopback, link-local, scheme, ...). */\n | 'ssrf_refused'\n /** HTTP response was a redirect (3xx) โ auto-follow is disabled. */\n | 'redirect_blocked'\n /** Non-2xx HTTP status. */\n | 'http_error'\n /** Response body exceeded 1 MiB cap. */\n | 'body_too_large'\n /** Response body wasn't valid JSON. */\n | 'invalid_json'\n /** SHA-256 of body didn't match the supplied digest. */\n | 'digest_mismatch'\n /** Network/timeout failure. */\n | 'network_error';\n\nexport class FormatSchemaFetchError extends Error {\n readonly code: FormatSchemaFetchErrorCode;\n readonly uri: string;\n readonly digest?: string;\n readonly httpStatus?: number;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: FormatSchemaFetchErrorCode,\n message: string,\n meta: { uri: string; digest?: string; httpStatus?: number; details?: Record<string, unknown> }\n ) {\n super(message);\n this.name = 'FormatSchemaFetchError';\n this.code = code;\n this.uri = meta.uri;\n this.digest = meta.digest;\n this.httpStatus = meta.httpStatus;\n this.details = meta.details;\n }\n}\n\nexport interface FormatSchemaFetchResult {\n /** The parsed JSON schema document. */\n schema: Record<string, unknown>;\n /** Echo of the input ref (handy for downstream caching). */\n ref: FormatSchemaRef;\n /**\n * Whether the result was served from the in-process cache. Helpful\n * for telemetry; fresh fetches and cache hits both return successful\n * results.\n */\n fromCache: boolean;\n}\n\nexport interface FetchFormatSchemaOptions {\n /**\n * Fetch timeout in ms. Default 5_000 per spec recommendation\n * (\"SDKs SHOULD apply a fetch timeout โค5 seconds\").\n */\n timeoutMs?: number;\n /**\n * Hard cap on response body bytes. Default 1 MiB per spec. Lower this\n * for tight environments; do not raise above the spec ceiling.\n */\n maxBodyBytes?: number;\n /**\n * Caller-scoped test/dev opt-in for loopback/private HTTP fetches.\n * Production callers should leave this false. IMDS/link-local\n * metadata endpoints remain blocked by `ssrfSafeFetch`.\n */\n allowInternalReferences?: boolean;\n /**\n * Override the module-level cache. Useful when callers want\n * per-session caches or to disable caching entirely\n * (`{ get: () => undefined, set: () => {} }`).\n */\n cache?: FormatSchemaCache;\n}\n\n/** Pluggable cache interface โ defaults to an in-process Map. */\nexport interface FormatSchemaCache {\n get(key: string): FormatSchemaFetchResult | undefined;\n set(key: string, value: FormatSchemaFetchResult): void;\n}\n\nconst DEFAULT_TIMEOUT_MS = 5_000;\nconst DEFAULT_MAX_BODY_BYTES = 1024 * 1024;\nconst DIGEST_RE = /^sha256:[0-9a-f]{64}$/;\n\nfunction cloneJsonRecord<T extends Record<string, unknown>>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction cloneFetchResult(result: FormatSchemaFetchResult, fromCache: boolean): FormatSchemaFetchResult {\n return {\n schema: cloneJsonRecord(result.schema),\n ref: { ...result.ref },\n fromCache,\n };\n}\n\nfunction defaultCache(): FormatSchemaCache {\n const store = new Map<string, FormatSchemaFetchResult>();\n return {\n get: key => store.get(key),\n set: (key, value) => {\n store.set(key, cloneFetchResult(value, false));\n },\n };\n}\n\nlet moduleCache = defaultCache();\n\n/** Test hook: drop the module-level cache. */\nexport function _resetFormatSchemaCache(): void {\n moduleCache = defaultCache();\n}\n\n/**\n * Fetch and digest-verify a format_schema reference. Returns the parsed\n * schema on success; throws {@link FormatSchemaFetchError} on every\n * failure mode so callers can surface a normalized diagnostic.\n */\nexport async function fetchFormatSchema(\n ref: FormatSchemaRef,\n options: FetchFormatSchemaOptions = {}\n): Promise<FormatSchemaFetchResult> {\n if (!ref || typeof ref.uri !== 'string' || typeof ref.digest !== 'string') {\n throw new FormatSchemaFetchError('invalid_ref', 'format_schema ref must carry { uri, digest }', {\n uri: ref?.uri ?? '<missing>',\n });\n }\n // Production: HTTPS-only per spec. Loopback test runs (gated by\n // ADCP_ALLOW_INTERNAL_PROBES=1) may use `http://` against a 127.0.0.1\n // mock โ same opt-in pattern as the discovery layer.\n const allowHttp = options.allowInternalReferences === true || isInternalProbesAllowed();\n if (!ref.uri.startsWith('https://') && !(allowHttp && ref.uri.startsWith('http://'))) {\n throw new FormatSchemaFetchError('invalid_ref', 'format_schema.uri must use https:// (spec normative)', {\n uri: ref.uri,\n });\n }\n if (!DIGEST_RE.test(ref.digest)) {\n throw new FormatSchemaFetchError(\n 'invalid_ref',\n 'format_schema.digest must be `sha256:` + 64 lowercase hex characters',\n { uri: ref.uri, digest: ref.digest }\n );\n }\n\n const cache = options.cache ?? moduleCache;\n const cacheKey = `${ref.uri}@${ref.digest}`;\n const cached = cache.get(cacheKey);\n if (cached) {\n return cloneFetchResult(cached, true);\n }\n\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;\n\n let response;\n try {\n response = await ssrfSafeFetch(ref.uri, {\n method: 'GET',\n timeoutMs,\n maxBodyBytes,\n headers: {\n accept: 'application/schema+json, application/json',\n },\n // Internal-probes opt-in mirrors the discovery layer โ production\n // stays HTTPS+non-private; loopback tests opt in via env.\n allowPrivateIp: allowHttp,\n });\n } catch (err) {\n if (err instanceof SsrfRefusedError) {\n if (err.code === 'body_exceeds_limit') {\n throw new FormatSchemaFetchError('body_too_large', err.message, { uri: ref.uri, digest: ref.digest });\n }\n throw new FormatSchemaFetchError('ssrf_refused', `SSRF guard refused: ${err.message}`, {\n uri: ref.uri,\n digest: ref.digest,\n details: { code: err.code, hostname: err.hostname },\n });\n }\n const message = err instanceof Error ? err.message : String(err);\n // Distinguish over-cap from generic network errors so callers can\n // surface the spec's \"body_too_large is a hard fail\" semantics.\n if (/body too large|maxBodyBytes/i.test(message)) {\n throw new FormatSchemaFetchError('body_too_large', message, { uri: ref.uri, digest: ref.digest });\n }\n throw new FormatSchemaFetchError('network_error', message, { uri: ref.uri, digest: ref.digest });\n }\n\n // Spec: \"HTTP redirects MUST be disabled.\" ssrfSafeFetch uses\n // `redirect: 'manual'`, so 3xx returns the redirect response. Treat\n // as a hard fail per the spec.\n if (response.status >= 300 && response.status < 400) {\n throw new FormatSchemaFetchError(\n 'redirect_blocked',\n `HTTP redirect (${response.status}) โ auto-follow disabled per spec`,\n {\n uri: ref.uri,\n digest: ref.digest,\n httpStatus: response.status,\n }\n );\n }\n if (response.status < 200 || response.status >= 300) {\n throw new FormatSchemaFetchError('http_error', `HTTP ${response.status}`, {\n uri: ref.uri,\n digest: ref.digest,\n httpStatus: response.status,\n });\n }\n\n const bodyBytes = response.body;\n const actualDigest = `sha256:${createHash('sha256').update(bodyBytes).digest('hex')}`;\n if (actualDigest !== ref.digest) {\n throw new FormatSchemaFetchError(\n 'digest_mismatch',\n `digest mismatch: expected ${ref.digest}, got ${actualDigest}`,\n { uri: ref.uri, digest: ref.digest, details: { actualDigest } }\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(new TextDecoder('utf-8').decode(bodyBytes));\n } catch (err) {\n throw new FormatSchemaFetchError(\n 'invalid_json',\n `response body is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n { uri: ref.uri, digest: ref.digest }\n );\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new FormatSchemaFetchError(\n 'invalid_json',\n 'response body is not a JSON object (JSON Schema documents are objects)',\n { uri: ref.uri, digest: ref.digest }\n );\n }\n\n const result: FormatSchemaFetchResult = {\n schema: parsed as Record<string, unknown>,\n ref: { ...ref },\n fromCache: false,\n };\n cache.set(cacheKey, result);\n return cloneFetchResult(result, false);\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 {
|
|
8
2
|
fetchFormatSchema,
|
|
9
3
|
FormatSchemaFetchError,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/v2/format-schema/index.ts"],"sourcesContent":["/**\n * Canonical reference resolver for AdCP 3.1 `format_schema` and\n * `platform_extensions` URI+digest references.\n *\n * Use the high-level resolver after `projectV1ProductToV2` or directly\n * on V2 declarations. It returns structured statuses instead of\n * throwing, keeps a caller-scoped immutable cache, resolves and compiles\n * custom format schemas, and uses the same hardened transport for\n * platform-extension definitions.\n *\n * ```ts\n * import { createCanonicalReferenceResolver } from '@adcp/sdk/v2/format-schema';\n *\n * const resolver = createCanonicalReferenceResolver();\n * const result = await resolver.resolveFormatSchema(decl.format_schema);\n * if (result.ok) {\n * // Use `result.document` to validate the placement manifest.\n * }\n * ```\n *\n * Implements the spec's normative fetch contract (HTTPS-only, SSRF\n * guards, no redirects, 1 MiB body cap, 5 s timeout, SHA-256 digest\n * verification, immutable `uri@digest` cache).\n */\n\nexport {\n fetchFormatSchema,\n FormatSchemaFetchError,\n _resetFormatSchemaCache,\n type FormatSchemaRef,\n type FormatSchemaFetchResult,\n type FormatSchemaFetchErrorCode,\n type FetchFormatSchemaOptions,\n type FormatSchemaCache,\n} from './fetch';\n\nexport {\n resolveSchemaRefs,\n SchemaRefSandboxError,\n DEFAULT_MAX_REF_DEPTH,\n DEFAULT_MAX_REF_COUNT,\n DEFAULT_MIRROR_HOST,\n DEFAULT_MIRROR_HOSTS,\n DEFAULT_MAX_KEYWORDS,\n DEFAULT_VALIDATION_BUDGET_MS,\n type SchemaRefSandboxErrorCode,\n type ResolveSchemaRefsOptions,\n type ResolveSchemaRefsResult,\n} from './sandbox-refs';\n\nexport {\n createCanonicalRefResolver,\n createCanonicalReferenceResolver,\n createMemoryCanonicalReferenceCache,\n resolveFormatSchema,\n resolvePlatformExtension,\n type CanonicalReferenceCache,\n type CanonicalRef,\n type CanonicalReferenceFailureResult,\n type CanonicalReferenceKind,\n type CanonicalReferenceResolvedResult,\n type CanonicalReferenceResolutionCode,\n type CanonicalReferenceResolutionResult,\n type CanonicalReferenceResolutionStatus,\n type CanonicalReferenceResolver,\n type CanonicalReferenceResolverOptions,\n type ResolveCanonicalReferenceOptions,\n} from './resolver';\n\nexport { findUnsafeRegexPattern, unsafeRegexDetails, type UnsafeRegexPattern } from './regex-safety';\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/v2/format-schema/index.ts"],"sourcesContent":["/**\n * Canonical reference resolver for AdCP 3.1 `format_schema` and\n * `platform_extensions` URI+digest references.\n *\n * Use the high-level resolver after `projectV1ProductToV2` or directly\n * on V2 declarations. It returns structured statuses instead of\n * throwing, keeps a caller-scoped immutable cache, resolves and compiles\n * custom format schemas, and uses the same hardened transport for\n * platform-extension definitions.\n *\n * ```ts\n * import { createCanonicalReferenceResolver } from '@adcp/sdk/v2/format-schema';\n *\n * const resolver = createCanonicalReferenceResolver();\n * const result = await resolver.resolveFormatSchema(decl.format_schema);\n * if (result.ok) {\n * // Use `result.document` to validate the placement manifest.\n * }\n * ```\n *\n * Implements the spec's normative fetch contract (HTTPS-only, SSRF\n * guards, no redirects, 1 MiB body cap, 5 s timeout, SHA-256 digest\n * verification, immutable `uri@digest` cache).\n */\n\nexport {\n fetchFormatSchema,\n FormatSchemaFetchError,\n _resetFormatSchemaCache,\n type FormatSchemaRef,\n type FormatSchemaFetchResult,\n type FormatSchemaFetchErrorCode,\n type FetchFormatSchemaOptions,\n type FormatSchemaCache,\n} from './fetch';\n\nexport {\n resolveSchemaRefs,\n SchemaRefSandboxError,\n DEFAULT_MAX_REF_DEPTH,\n DEFAULT_MAX_REF_COUNT,\n DEFAULT_MIRROR_HOST,\n DEFAULT_MIRROR_HOSTS,\n DEFAULT_MAX_KEYWORDS,\n DEFAULT_VALIDATION_BUDGET_MS,\n type SchemaRefSandboxErrorCode,\n type ResolveSchemaRefsOptions,\n type ResolveSchemaRefsResult,\n} from './sandbox-refs';\n\nexport {\n createCanonicalRefResolver,\n createCanonicalReferenceResolver,\n createMemoryCanonicalReferenceCache,\n resolveFormatSchema,\n resolvePlatformExtension,\n type CanonicalReferenceCache,\n type CanonicalRef,\n type CanonicalReferenceFailureResult,\n type CanonicalReferenceKind,\n type CanonicalReferenceResolvedResult,\n type CanonicalReferenceResolutionCode,\n type CanonicalReferenceResolutionResult,\n type CanonicalReferenceResolutionStatus,\n type CanonicalReferenceResolver,\n type CanonicalReferenceResolverOptions,\n type ResolveCanonicalReferenceOptions,\n} from './resolver';\n\nexport { findUnsafeRegexPattern, unsafeRegexDetails, type UnsafeRegexPattern } from './regex-safety';\n"],"mappings":"AAyBA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAYK;AAEP,SAAS,wBAAwB,0BAAmD;","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 { createHash } from "crypto";
|
|
8
2
|
const SCHEMA_VALUE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
9
3
|
"additionalItems",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/v2/format-schema/regex-safety.ts"],"sourcesContent":["import { createHash } from 'crypto';\n\nexport interface UnsafeRegexPattern {\n location: string;\n pattern: string;\n reason: 'nested_unbounded_quantifier' | 'ambiguous_repeated_alternation';\n}\n\ninterface RegexGroup {\n body: string;\n end: number;\n}\n\ntype QuantifierInfo = {\n min: number;\n max: number | null;\n end: number;\n unbounded: boolean;\n variable: boolean;\n};\n\nconst SCHEMA_VALUE_KEYWORDS = new Set([\n 'additionalItems',\n 'additionalProperties',\n 'contains',\n 'contentSchema',\n 'else',\n 'if',\n 'items',\n 'not',\n 'propertyNames',\n 'then',\n 'unevaluatedItems',\n 'unevaluatedProperties',\n]);\n\nconst SCHEMA_ARRAY_KEYWORDS = new Set(['allOf', 'anyOf', 'oneOf', 'prefixItems']);\nconst SCHEMA_MAP_KEYWORDS = new Set(['$defs', 'definitions', 'dependentSchemas', 'properties']);\n\nexport function unsafeRegexDetails(pattern: UnsafeRegexPattern): Record<string, unknown> {\n return {\n location: pattern.location,\n reason: pattern.reason,\n patternLength: pattern.pattern.length,\n patternPreview: pattern.pattern.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/g, '?').slice(0, 120),\n patternSha256: createHash('sha256').update(pattern.pattern).digest('hex'),\n };\n}\n\nexport function findUnsafeRegexPattern(root: unknown): UnsafeRegexPattern | undefined {\n const seen = new Set<unknown>();\n\n function walkSchema(node: unknown, pointer: string): UnsafeRegexPattern | undefined {\n if (!node || typeof node !== 'object') return undefined;\n if (seen.has(node)) return undefined;\n seen.add(node);\n\n if (Array.isArray(node)) return walkSchemaArray(node, pointer);\n\n const obj = node as Record<string, unknown>;\n\n if (typeof obj.pattern === 'string') {\n const unsafe = analyzeRegexPattern(obj.pattern, `${pointer}/pattern`);\n if (unsafe) return unsafe;\n }\n\n const patternProperties = obj.patternProperties;\n if (patternProperties && typeof patternProperties === 'object' && !Array.isArray(patternProperties)) {\n const basePointer = `${pointer}/patternProperties`;\n for (const [pattern, subschema] of Object.entries(patternProperties as Record<string, unknown>)) {\n const patternPointer = `${basePointer}/${escapeJsonPointer(pattern)}`;\n const unsafe = analyzeRegexPattern(pattern, patternPointer) ?? walkSchema(subschema, patternPointer);\n if (unsafe) return unsafe;\n }\n }\n\n for (const keyword of SCHEMA_VALUE_KEYWORDS) {\n const unsafe = walkSchemaValue(obj[keyword], `${pointer}/${keyword}`);\n if (unsafe) return unsafe;\n }\n\n for (const keyword of SCHEMA_ARRAY_KEYWORDS) {\n const unsafe = walkSchemaArrayValue(obj[keyword], `${pointer}/${keyword}`);\n if (unsafe) return unsafe;\n }\n\n for (const keyword of SCHEMA_MAP_KEYWORDS) {\n const unsafe = walkSchemaMap(obj[keyword], `${pointer}/${keyword}`);\n if (unsafe) return unsafe;\n }\n\n const dependencies = obj.dependencies;\n if (dependencies && typeof dependencies === 'object' && !Array.isArray(dependencies)) {\n for (const [key, value] of Object.entries(dependencies as Record<string, unknown>)) {\n if (!value || typeof value !== 'object' || Array.isArray(value)) continue;\n const unsafe = walkSchema(value, `${pointer}/dependencies/${escapeJsonPointer(key)}`);\n if (unsafe) return unsafe;\n }\n }\n\n return undefined;\n }\n\n function walkSchemaValue(value: unknown, pointer: string): UnsafeRegexPattern | undefined {\n if (Array.isArray(value)) return walkSchemaArray(value, pointer);\n return walkSchema(value, pointer);\n }\n\n function walkSchemaArrayValue(value: unknown, pointer: string): UnsafeRegexPattern | undefined {\n if (!Array.isArray(value)) return undefined;\n return walkSchemaArray(value, pointer);\n }\n\n function walkSchemaArray(value: readonly unknown[], pointer: string): UnsafeRegexPattern | undefined {\n for (let index = 0; index < value.length; index += 1) {\n const unsafe = walkSchema(value[index], `${pointer}/${index}`);\n if (unsafe) return unsafe;\n }\n return undefined;\n }\n\n function walkSchemaMap(value: unknown, pointer: string): UnsafeRegexPattern | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n for (const [key, subschema] of Object.entries(value as Record<string, unknown>)) {\n const unsafe = walkSchema(subschema, `${pointer}/${escapeJsonPointer(key)}`);\n if (unsafe) return unsafe;\n }\n return undefined;\n }\n\n return walkSchema(root, '');\n}\n\nfunction analyzeRegexPattern(pattern: string, location: string): UnsafeRegexPattern | undefined {\n for (const group of collectGroups(pattern)) {\n const quantifier = readQuantifier(pattern, group.end + 1);\n if (!quantifier?.unbounded) continue;\n\n if (isSingleVariableRepeat(group.body)) {\n return { location, pattern, reason: 'nested_unbounded_quantifier' };\n }\n if (hasAmbiguousAlternationByTokenPrefix(group.body)) {\n return { location, pattern, reason: 'ambiguous_repeated_alternation' };\n }\n }\n return undefined;\n}\n\nfunction collectGroups(pattern: string): RegexGroup[] {\n const groups: RegexGroup[] = [];\n const stack: number[] = [];\n let escaped = false;\n let inClass = false;\n\n for (let index = 0; index < pattern.length; index += 1) {\n const char = pattern[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === '[') {\n inClass = true;\n continue;\n }\n if (char === ']' && inClass) {\n inClass = false;\n continue;\n }\n if (inClass) continue;\n if (char === '(') {\n stack.push(index);\n continue;\n }\n if (char === ')') {\n const start = stack.pop();\n if (start !== undefined) {\n groups.push({ body: pattern.slice(start + 1, index), end: index });\n }\n }\n }\n\n return groups;\n}\n\nfunction isSingleVariableRepeat(source: string): boolean {\n const normalized = stripGroupPrefix(source);\n const first = readRegexAtom(normalized, 0);\n if (!first) return false;\n\n const quantifier = readQuantifier(normalized, first.end);\n if (!quantifier?.variable) return false;\n\n return quantifier.end === normalized.length;\n}\n\nfunction readRegexAtom(source: string, index: number): { end: number } | undefined {\n const char = source[index];\n if (!char) return undefined;\n\n if (char === '\\\\') {\n return index + 1 < source.length ? { end: index + 2 } : undefined;\n }\n if (char === '[') {\n return readCharacterClass(source, index);\n }\n if (char === '(') {\n return readGroup(source, index);\n }\n if ('^$|?*+{}'.includes(char)) return undefined;\n return { end: index + 1 };\n}\n\nfunction readCharacterClass(source: string, index: number): { end: number } | undefined {\n let escaped = false;\n\n for (let cursor = index + 1; cursor < source.length; cursor += 1) {\n const char = source[cursor];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === ']') return { end: cursor + 1 };\n }\n\n return undefined;\n}\n\nfunction readGroup(source: string, index: number): { end: number } | undefined {\n let escaped = false;\n let inClass = false;\n let depth = 0;\n\n for (let cursor = index; cursor < source.length; cursor += 1) {\n const char = source[cursor];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === '[') {\n inClass = true;\n continue;\n }\n if (char === ']' && inClass) {\n inClass = false;\n continue;\n }\n if (inClass) continue;\n if (char === '(') {\n depth += 1;\n continue;\n }\n if (char === ')') {\n depth -= 1;\n if (depth === 0) return { end: cursor + 1 };\n }\n }\n\n return undefined;\n}\n\nfunction readQuantifier(source: string, index: number): QuantifierInfo | undefined {\n const char = source[index];\n if (char === '?') return { min: 0, max: 1, end: index + 1, unbounded: false, variable: true };\n if (char === '*') return { min: 0, max: null, end: index + 1, unbounded: true, variable: true };\n if (char === '+') return { min: 1, max: null, end: index + 1, unbounded: true, variable: true };\n if (char !== '{') return undefined;\n\n const match = /^\\{(\\d+)(?:,(\\d*))?\\}/.exec(source.slice(index));\n if (!match) return undefined;\n\n const min = Number(match[1]);\n const max = match[2] === '' ? null : Number(match[2] ?? match[1]);\n return {\n min,\n max,\n end: index + match[0].length,\n unbounded: max === null,\n variable: max === null || min !== max,\n };\n}\n\nfunction hasAmbiguousAlternationByTokenPrefix(source: string): boolean {\n const alternatives = splitTopLevelAlternatives(stripGroupPrefix(source));\n if (alternatives.length < 2) return false;\n\n const tokenized = alternatives.map(tokenizeRegexAtoms).filter(tokens => tokens.length > 0);\n for (let left = 0; left < tokenized.length; left += 1) {\n for (let right = 0; right < tokenized.length; right += 1) {\n const leftTokens = tokenized[left];\n const rightTokens = tokenized[right];\n if (leftTokens && rightTokens && left !== right && tokensStartWith(rightTokens, leftTokens)) return true;\n }\n }\n return false;\n}\n\nfunction tokenizeRegexAtoms(source: string): string[] {\n const tokens: string[] = [];\n let cursor = 0;\n\n while (cursor < source.length) {\n const atom = readRegexAtom(source, cursor);\n if (!atom) break;\n const raw = source.slice(cursor, atom.end);\n const quantifier = readQuantifier(source, atom.end);\n tokens.push(`${raw}${quantifier ? source.slice(atom.end, quantifier.end) : ''}`);\n cursor = quantifier?.end ?? atom.end;\n }\n\n return tokens;\n}\n\nfunction tokensStartWith(tokens: readonly string[], prefix: readonly string[]): boolean {\n if (prefix.length >= tokens.length) return false;\n for (let index = 0; index < prefix.length; index += 1) {\n if (tokens[index] !== prefix[index]) return false;\n }\n return true;\n}\n\nfunction splitTopLevelAlternatives(source: string): string[] {\n const alternatives: string[] = [];\n let start = 0;\n let escaped = false;\n let inClass = false;\n let depth = 0;\n\n for (let index = 0; index < source.length; index += 1) {\n const char = source[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === '[') {\n inClass = true;\n continue;\n }\n if (char === ']' && inClass) {\n inClass = false;\n continue;\n }\n if (inClass) continue;\n if (char === '(') {\n depth += 1;\n continue;\n }\n if (char === ')' && depth > 0) {\n depth -= 1;\n continue;\n }\n if (char === '|' && depth === 0) {\n alternatives.push(source.slice(start, index));\n start = index + 1;\n }\n }\n alternatives.push(source.slice(start));\n return alternatives;\n}\n\nfunction stripGroupPrefix(source: string): string {\n if (source.startsWith('?:') || source.startsWith('?=') || source.startsWith('?!')) return source.slice(2);\n if (source.startsWith('?<=') || source.startsWith('?<!')) return source.slice(3);\n if (source.startsWith('?<')) {\n const end = source.indexOf('>');\n if (end > 2) return source.slice(end + 1);\n }\n return source;\n}\n\nfunction escapeJsonPointer(value: string): string {\n return value.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/v2/format-schema/regex-safety.ts"],"sourcesContent":["import { createHash } from 'crypto';\n\nexport interface UnsafeRegexPattern {\n location: string;\n pattern: string;\n reason: 'nested_unbounded_quantifier' | 'ambiguous_repeated_alternation';\n}\n\ninterface RegexGroup {\n body: string;\n end: number;\n}\n\ntype QuantifierInfo = {\n min: number;\n max: number | null;\n end: number;\n unbounded: boolean;\n variable: boolean;\n};\n\nconst SCHEMA_VALUE_KEYWORDS = new Set([\n 'additionalItems',\n 'additionalProperties',\n 'contains',\n 'contentSchema',\n 'else',\n 'if',\n 'items',\n 'not',\n 'propertyNames',\n 'then',\n 'unevaluatedItems',\n 'unevaluatedProperties',\n]);\n\nconst SCHEMA_ARRAY_KEYWORDS = new Set(['allOf', 'anyOf', 'oneOf', 'prefixItems']);\nconst SCHEMA_MAP_KEYWORDS = new Set(['$defs', 'definitions', 'dependentSchemas', 'properties']);\n\nexport function unsafeRegexDetails(pattern: UnsafeRegexPattern): Record<string, unknown> {\n return {\n location: pattern.location,\n reason: pattern.reason,\n patternLength: pattern.pattern.length,\n patternPreview: pattern.pattern.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/g, '?').slice(0, 120),\n patternSha256: createHash('sha256').update(pattern.pattern).digest('hex'),\n };\n}\n\nexport function findUnsafeRegexPattern(root: unknown): UnsafeRegexPattern | undefined {\n const seen = new Set<unknown>();\n\n function walkSchema(node: unknown, pointer: string): UnsafeRegexPattern | undefined {\n if (!node || typeof node !== 'object') return undefined;\n if (seen.has(node)) return undefined;\n seen.add(node);\n\n if (Array.isArray(node)) return walkSchemaArray(node, pointer);\n\n const obj = node as Record<string, unknown>;\n\n if (typeof obj.pattern === 'string') {\n const unsafe = analyzeRegexPattern(obj.pattern, `${pointer}/pattern`);\n if (unsafe) return unsafe;\n }\n\n const patternProperties = obj.patternProperties;\n if (patternProperties && typeof patternProperties === 'object' && !Array.isArray(patternProperties)) {\n const basePointer = `${pointer}/patternProperties`;\n for (const [pattern, subschema] of Object.entries(patternProperties as Record<string, unknown>)) {\n const patternPointer = `${basePointer}/${escapeJsonPointer(pattern)}`;\n const unsafe = analyzeRegexPattern(pattern, patternPointer) ?? walkSchema(subschema, patternPointer);\n if (unsafe) return unsafe;\n }\n }\n\n for (const keyword of SCHEMA_VALUE_KEYWORDS) {\n const unsafe = walkSchemaValue(obj[keyword], `${pointer}/${keyword}`);\n if (unsafe) return unsafe;\n }\n\n for (const keyword of SCHEMA_ARRAY_KEYWORDS) {\n const unsafe = walkSchemaArrayValue(obj[keyword], `${pointer}/${keyword}`);\n if (unsafe) return unsafe;\n }\n\n for (const keyword of SCHEMA_MAP_KEYWORDS) {\n const unsafe = walkSchemaMap(obj[keyword], `${pointer}/${keyword}`);\n if (unsafe) return unsafe;\n }\n\n const dependencies = obj.dependencies;\n if (dependencies && typeof dependencies === 'object' && !Array.isArray(dependencies)) {\n for (const [key, value] of Object.entries(dependencies as Record<string, unknown>)) {\n if (!value || typeof value !== 'object' || Array.isArray(value)) continue;\n const unsafe = walkSchema(value, `${pointer}/dependencies/${escapeJsonPointer(key)}`);\n if (unsafe) return unsafe;\n }\n }\n\n return undefined;\n }\n\n function walkSchemaValue(value: unknown, pointer: string): UnsafeRegexPattern | undefined {\n if (Array.isArray(value)) return walkSchemaArray(value, pointer);\n return walkSchema(value, pointer);\n }\n\n function walkSchemaArrayValue(value: unknown, pointer: string): UnsafeRegexPattern | undefined {\n if (!Array.isArray(value)) return undefined;\n return walkSchemaArray(value, pointer);\n }\n\n function walkSchemaArray(value: readonly unknown[], pointer: string): UnsafeRegexPattern | undefined {\n for (let index = 0; index < value.length; index += 1) {\n const unsafe = walkSchema(value[index], `${pointer}/${index}`);\n if (unsafe) return unsafe;\n }\n return undefined;\n }\n\n function walkSchemaMap(value: unknown, pointer: string): UnsafeRegexPattern | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n for (const [key, subschema] of Object.entries(value as Record<string, unknown>)) {\n const unsafe = walkSchema(subschema, `${pointer}/${escapeJsonPointer(key)}`);\n if (unsafe) return unsafe;\n }\n return undefined;\n }\n\n return walkSchema(root, '');\n}\n\nfunction analyzeRegexPattern(pattern: string, location: string): UnsafeRegexPattern | undefined {\n for (const group of collectGroups(pattern)) {\n const quantifier = readQuantifier(pattern, group.end + 1);\n if (!quantifier?.unbounded) continue;\n\n if (isSingleVariableRepeat(group.body)) {\n return { location, pattern, reason: 'nested_unbounded_quantifier' };\n }\n if (hasAmbiguousAlternationByTokenPrefix(group.body)) {\n return { location, pattern, reason: 'ambiguous_repeated_alternation' };\n }\n }\n return undefined;\n}\n\nfunction collectGroups(pattern: string): RegexGroup[] {\n const groups: RegexGroup[] = [];\n const stack: number[] = [];\n let escaped = false;\n let inClass = false;\n\n for (let index = 0; index < pattern.length; index += 1) {\n const char = pattern[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === '[') {\n inClass = true;\n continue;\n }\n if (char === ']' && inClass) {\n inClass = false;\n continue;\n }\n if (inClass) continue;\n if (char === '(') {\n stack.push(index);\n continue;\n }\n if (char === ')') {\n const start = stack.pop();\n if (start !== undefined) {\n groups.push({ body: pattern.slice(start + 1, index), end: index });\n }\n }\n }\n\n return groups;\n}\n\nfunction isSingleVariableRepeat(source: string): boolean {\n const normalized = stripGroupPrefix(source);\n const first = readRegexAtom(normalized, 0);\n if (!first) return false;\n\n const quantifier = readQuantifier(normalized, first.end);\n if (!quantifier?.variable) return false;\n\n return quantifier.end === normalized.length;\n}\n\nfunction readRegexAtom(source: string, index: number): { end: number } | undefined {\n const char = source[index];\n if (!char) return undefined;\n\n if (char === '\\\\') {\n return index + 1 < source.length ? { end: index + 2 } : undefined;\n }\n if (char === '[') {\n return readCharacterClass(source, index);\n }\n if (char === '(') {\n return readGroup(source, index);\n }\n if ('^$|?*+{}'.includes(char)) return undefined;\n return { end: index + 1 };\n}\n\nfunction readCharacterClass(source: string, index: number): { end: number } | undefined {\n let escaped = false;\n\n for (let cursor = index + 1; cursor < source.length; cursor += 1) {\n const char = source[cursor];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === ']') return { end: cursor + 1 };\n }\n\n return undefined;\n}\n\nfunction readGroup(source: string, index: number): { end: number } | undefined {\n let escaped = false;\n let inClass = false;\n let depth = 0;\n\n for (let cursor = index; cursor < source.length; cursor += 1) {\n const char = source[cursor];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === '[') {\n inClass = true;\n continue;\n }\n if (char === ']' && inClass) {\n inClass = false;\n continue;\n }\n if (inClass) continue;\n if (char === '(') {\n depth += 1;\n continue;\n }\n if (char === ')') {\n depth -= 1;\n if (depth === 0) return { end: cursor + 1 };\n }\n }\n\n return undefined;\n}\n\nfunction readQuantifier(source: string, index: number): QuantifierInfo | undefined {\n const char = source[index];\n if (char === '?') return { min: 0, max: 1, end: index + 1, unbounded: false, variable: true };\n if (char === '*') return { min: 0, max: null, end: index + 1, unbounded: true, variable: true };\n if (char === '+') return { min: 1, max: null, end: index + 1, unbounded: true, variable: true };\n if (char !== '{') return undefined;\n\n const match = /^\\{(\\d+)(?:,(\\d*))?\\}/.exec(source.slice(index));\n if (!match) return undefined;\n\n const min = Number(match[1]);\n const max = match[2] === '' ? null : Number(match[2] ?? match[1]);\n return {\n min,\n max,\n end: index + match[0].length,\n unbounded: max === null,\n variable: max === null || min !== max,\n };\n}\n\nfunction hasAmbiguousAlternationByTokenPrefix(source: string): boolean {\n const alternatives = splitTopLevelAlternatives(stripGroupPrefix(source));\n if (alternatives.length < 2) return false;\n\n const tokenized = alternatives.map(tokenizeRegexAtoms).filter(tokens => tokens.length > 0);\n for (let left = 0; left < tokenized.length; left += 1) {\n for (let right = 0; right < tokenized.length; right += 1) {\n const leftTokens = tokenized[left];\n const rightTokens = tokenized[right];\n if (leftTokens && rightTokens && left !== right && tokensStartWith(rightTokens, leftTokens)) return true;\n }\n }\n return false;\n}\n\nfunction tokenizeRegexAtoms(source: string): string[] {\n const tokens: string[] = [];\n let cursor = 0;\n\n while (cursor < source.length) {\n const atom = readRegexAtom(source, cursor);\n if (!atom) break;\n const raw = source.slice(cursor, atom.end);\n const quantifier = readQuantifier(source, atom.end);\n tokens.push(`${raw}${quantifier ? source.slice(atom.end, quantifier.end) : ''}`);\n cursor = quantifier?.end ?? atom.end;\n }\n\n return tokens;\n}\n\nfunction tokensStartWith(tokens: readonly string[], prefix: readonly string[]): boolean {\n if (prefix.length >= tokens.length) return false;\n for (let index = 0; index < prefix.length; index += 1) {\n if (tokens[index] !== prefix[index]) return false;\n }\n return true;\n}\n\nfunction splitTopLevelAlternatives(source: string): string[] {\n const alternatives: string[] = [];\n let start = 0;\n let escaped = false;\n let inClass = false;\n let depth = 0;\n\n for (let index = 0; index < source.length; index += 1) {\n const char = source[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === '[') {\n inClass = true;\n continue;\n }\n if (char === ']' && inClass) {\n inClass = false;\n continue;\n }\n if (inClass) continue;\n if (char === '(') {\n depth += 1;\n continue;\n }\n if (char === ')' && depth > 0) {\n depth -= 1;\n continue;\n }\n if (char === '|' && depth === 0) {\n alternatives.push(source.slice(start, index));\n start = index + 1;\n }\n }\n alternatives.push(source.slice(start));\n return alternatives;\n}\n\nfunction stripGroupPrefix(source: string): string {\n if (source.startsWith('?:') || source.startsWith('?=') || source.startsWith('?!')) return source.slice(2);\n if (source.startsWith('?<=') || source.startsWith('?<!')) return source.slice(3);\n if (source.startsWith('?<')) {\n const end = source.indexOf('>');\n if (end > 2) return source.slice(end + 1);\n }\n return source;\n}\n\nfunction escapeJsonPointer(value: string): string {\n return value.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from
|
|
2
|
-
import { dirname as __adcpDirname } from
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const Ajv2019 = require("ajv/dist/2019");
|
|
1
|
+
import { fileURLToPath as __adcpFileURLToPath } from "node:url";
|
|
2
|
+
import { dirname as __adcpDirname } from "node:path";
|
|
3
|
+
import { createRequire as __adcpCreateRequire } from "node:module";
|
|
4
|
+
const __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));
|
|
5
|
+
const require2 = __adcpCreateRequire(import.meta.url);
|
|
6
|
+
const Ajv2019 = require2("ajv/dist/2019");
|
|
8
7
|
import addFormats from "ajv-formats";
|
|
9
|
-
const draft7MetaSchema =
|
|
8
|
+
const draft7MetaSchema = require2("ajv/dist/refs/json-schema-draft-07.json");
|
|
10
9
|
import {
|
|
11
10
|
fetchFormatSchema,
|
|
12
11
|
FormatSchemaFetchError
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/v2/format-schema/resolver.ts"],"sourcesContent":["// 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/2019.js`. The ESM build gets a\n// `createRequire` shim, so `require` is available in both formats.\nconst Ajv2019 = require('ajv/dist/2019') as typeof import('ajv/dist/2019').default;\nimport addFormats from 'ajv-formats';\n// Loaded via `require` (not a JSON `import`) so it resolves in both CJS and\n// ESM without a Node import attribute; the ESM build gets a `createRequire`\n// shim for this module.\nconst draft7MetaSchema = require('ajv/dist/refs/json-schema-draft-07.json');\nimport {\n fetchFormatSchema,\n FormatSchemaFetchError,\n type FetchFormatSchemaOptions,\n type FormatSchemaCache,\n type FormatSchemaFetchErrorCode,\n type FormatSchemaFetchResult,\n type FormatSchemaRef,\n} from './fetch';\nimport {\n DEFAULT_MAX_KEYWORDS,\n DEFAULT_MAX_REF_COUNT,\n DEFAULT_MAX_REF_DEPTH,\n resolveSchemaRefs,\n SchemaRefSandboxError,\n type ResolveSchemaRefsOptions,\n type SchemaRefSandboxErrorCode,\n} from './sandbox-refs';\nimport { findUnsafeRegexPattern, unsafeRegexDetails } from './regex-safety';\n\nexport type CanonicalReferenceKind = 'format_schema' | 'platform_extensions';\nexport type CanonicalRef = FormatSchemaRef;\n\nexport type CanonicalReferenceResolutionStatus =\n | 'resolved'\n | 'invalid_ref'\n | 'blocked_unsafe_url'\n | 'digest_mismatch'\n | 'invalid_schema'\n | 'unresolvable';\n\nexport type CanonicalReferenceResolutionCode =\n | FormatSchemaFetchErrorCode\n | SchemaRefSandboxErrorCode\n | 'schema_dialect_unsupported'\n | 'schema_compile_failed'\n | 'schema_keyword_limit_exceeded'\n | 'budget_exceeded';\n\nexport interface CanonicalReferenceResolvedResult {\n ok: true;\n status: 'resolved';\n kind: CanonicalReferenceKind;\n ref: FormatSchemaRef;\n /**\n * Resolved document. For `format_schema`, every allowed `$ref` has\n * been inlined and the result has compiled as JSON Schema. For\n * `platform_extensions`, this is the fetched JSON object.\n */\n document: Record<string, unknown>;\n /** Original digest-verified document, before `$ref` inlining. */\n rawDocument: Record<string, unknown>;\n /** True when returned from the caller-scoped immutable cache. */\n fromCache: boolean;\n /** `format_schema` only: count of `$ref` occurrences resolved. */\n refCount?: number;\n /** `format_schema` only: deepest transitive `$ref` depth observed. */\n maxDepthSeen?: number;\n}\n\nexport interface CanonicalReferenceFailureResult {\n ok: false;\n status: Exclude<CanonicalReferenceResolutionStatus, 'resolved'>;\n kind: CanonicalReferenceKind;\n ref: Partial<FormatSchemaRef>;\n /** Stable transport/schema subreason. Same value as `code`. */\n reason: CanonicalReferenceResolutionCode;\n code: CanonicalReferenceResolutionCode;\n /** True for transient network/server/cap failures callers may retry. */\n retryable: boolean;\n message: string;\n httpStatus?: number;\n details?: Record<string, unknown>;\n}\n\nexport type CanonicalReferenceResolutionResult = CanonicalReferenceResolvedResult | CanonicalReferenceFailureResult;\n\nexport interface CanonicalReferenceCache {\n get(key: string): CanonicalReferenceResolvedResult | undefined;\n set(key: string, value: CanonicalReferenceResolvedResult): void;\n}\n\nexport interface CanonicalReferenceResolverOptions {\n timeoutMs?: number;\n maxBodyBytes?: number;\n cache?: CanonicalReferenceCache;\n maxRefDepth?: number;\n maxRefCount?: number;\n maxKeywords?: number;\n allowInternalReferences?: boolean;\n mirrorHost?: ResolveSchemaRefsOptions['mirrorHost'];\n mirrorHosts?: ResolveSchemaRefsOptions['mirrorHosts'];\n fetchExternal?: ResolveSchemaRefsOptions['fetchExternal'];\n}\n\nexport interface ResolveCanonicalReferenceOptions extends CanonicalReferenceResolverOptions {\n kind: CanonicalReferenceKind;\n}\n\nexport interface CanonicalReferenceResolver {\n resolveReference(\n ref: FormatSchemaRef,\n options: ResolveCanonicalReferenceOptions\n ): Promise<CanonicalReferenceResolutionResult>;\n resolveFormatSchema(\n ref: FormatSchemaRef,\n options?: CanonicalReferenceResolverOptions\n ): Promise<CanonicalReferenceResolutionResult>;\n resolvePlatformExtension(\n ref: FormatSchemaRef,\n options?: CanonicalReferenceResolverOptions\n ): Promise<CanonicalReferenceResolutionResult>;\n}\n\nexport function createMemoryCanonicalReferenceCache(): CanonicalReferenceCache {\n const store = new Map<string, CanonicalReferenceResolvedResult>();\n return {\n get: key => {\n const cached = store.get(key);\n return cached ? cloneResolvedResult(cached, false) : undefined;\n },\n set: (key, value) => {\n store.set(key, cloneResolvedResult(value, false));\n },\n };\n}\n\nfunction createMemoryFormatSchemaCache(): FormatSchemaCache {\n const store = new Map<string, FormatSchemaFetchResult>();\n return {\n get: key => store.get(key),\n set: (key, value) => {\n store.set(key, value);\n },\n };\n}\n\nfunction cacheKey(kind: CanonicalReferenceKind, ref: FormatSchemaRef): string {\n return `${kind}:${ref.uri}@${ref.digest}`;\n}\n\nfunction cloneJsonRecord<T extends Record<string, unknown>>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction cloneResolvedResult(\n result: CanonicalReferenceResolvedResult,\n fromCache: boolean\n): CanonicalReferenceResolvedResult {\n return {\n ...result,\n ref: { ...result.ref },\n document: cloneJsonRecord(result.document),\n rawDocument: cloneJsonRecord(result.rawDocument),\n fromCache,\n };\n}\n\nfunction toFetchOptions(\n options: CanonicalReferenceResolverOptions,\n fetchCache: FormatSchemaCache\n): FetchFormatSchemaOptions {\n return {\n timeoutMs: options.timeoutMs,\n maxBodyBytes: options.maxBodyBytes,\n allowInternalReferences: options.allowInternalReferences,\n cache: fetchCache,\n };\n}\n\nfunction fail(\n kind: CanonicalReferenceKind,\n ref: Partial<FormatSchemaRef>,\n status: CanonicalReferenceFailureResult['status'],\n code: CanonicalReferenceResolutionCode,\n message: string,\n meta: { httpStatus?: number; details?: Record<string, unknown>; retryable?: boolean } = {}\n): CanonicalReferenceFailureResult {\n return {\n ok: false,\n status,\n kind,\n ref,\n reason: code,\n code,\n retryable: meta.retryable ?? status === 'unresolvable',\n message,\n httpStatus: meta.httpStatus,\n details: meta.details,\n };\n}\n\nfunction mapFetchError(kind: CanonicalReferenceKind, ref: Partial<FormatSchemaRef>, err: FormatSchemaFetchError) {\n if (err.code === 'digest_mismatch') {\n return fail(kind, ref, 'digest_mismatch', err.code, err.message, {\n details: err.details,\n retryable: false,\n });\n }\n if (\n err.code === 'ssrf_refused' &&\n (err.details?.code === 'dns_lookup_failed' ||\n err.details?.code === 'dns_empty' ||\n err.details?.code === 'body_exceeds_limit')\n ) {\n return fail(kind, ref, 'unresolvable', err.code, err.message, {\n details: err.details,\n retryable: true,\n });\n }\n if (\n err.code === 'ssrf_refused' ||\n err.code === 'redirect_blocked' ||\n (err.code === 'invalid_ref' && /uri must use https/i.test(err.message))\n ) {\n return fail(kind, ref, 'blocked_unsafe_url', err.code, err.message, {\n httpStatus: err.httpStatus,\n details: err.details,\n retryable: false,\n });\n }\n if (err.code === 'invalid_ref') {\n return fail(kind, ref, 'invalid_ref', err.code, err.message, { details: err.details, retryable: false });\n }\n if (err.code === 'invalid_json') {\n return fail(kind, ref, 'invalid_schema', err.code, err.message, { details: err.details, retryable: false });\n }\n return fail(kind, ref, 'unresolvable', err.code, err.message, {\n httpStatus: err.httpStatus,\n details: err.details,\n retryable: true,\n });\n}\n\nfunction mapSandboxError(kind: CanonicalReferenceKind, ref: FormatSchemaRef, err: SchemaRefSandboxError) {\n if (err.code === 'fetch_failed' && err.details?.transient === true) {\n return fail(kind, ref, 'unresolvable', err.code, err.message, { details: err.details, retryable: true });\n }\n if (err.code === 'fetch_failed' && typeof err.details?.httpStatus === 'number') {\n const httpStatus = err.details.httpStatus;\n if (httpStatus >= 300 && httpStatus < 400) {\n return fail(kind, ref, 'blocked_unsafe_url', err.code, err.message, { details: err.details, retryable: false });\n }\n return fail(kind, ref, 'unresolvable', err.code, err.message, {\n details: err.details,\n retryable: httpStatus === 404 || httpStatus >= 500,\n });\n }\n const status =\n err.code === 'file_scheme_rejected' || err.code === 'cross_origin_rejected'\n ? 'blocked_unsafe_url'\n : 'invalid_schema';\n return fail(kind, ref, status, err.code, err.message, { details: err.details, retryable: false });\n}\n\nconst DRAFT_07_DIALECTS = new Set([\n 'http://json-schema.org/draft-07/schema',\n 'https://json-schema.org/draft-07/schema',\n]);\nconst DRAFT_2019_09_DIALECTS = new Set([\n 'http://json-schema.org/draft/2019-09/schema',\n 'https://json-schema.org/draft/2019-09/schema',\n]);\n\nfunction normalizeDialect(dialect: string | undefined): 'draft-07' | 'draft-2019-09' | undefined {\n if (!dialect) return 'draft-2019-09';\n const normalized = dialect.endsWith('#') ? dialect.slice(0, -1) : dialect;\n if (DRAFT_07_DIALECTS.has(normalized)) return 'draft-07';\n if (DRAFT_2019_09_DIALECTS.has(normalized)) return 'draft-2019-09';\n return undefined;\n}\n\nfunction countSchemaKeywords(node: unknown): number {\n if (node === null || typeof node !== 'object') return 0;\n if (Array.isArray(node)) return node.reduce((sum, item) => sum + countSchemaKeywords(item), 0);\n let count = 0;\n for (const value of Object.values(node as Record<string, unknown>)) {\n count += 1;\n count += countSchemaKeywords(value);\n }\n return count;\n}\n\nfunction validateJsonSchema(\n schema: Record<string, unknown>,\n maxKeywords: number\n):\n | { ok: true }\n | { ok: false; code: CanonicalReferenceResolutionCode; message: string; details?: Record<string, unknown> } {\n const dialect = typeof schema.$schema === 'string' ? schema.$schema : undefined;\n const normalizedDialect = normalizeDialect(dialect);\n if (!normalizedDialect) {\n return {\n ok: false,\n code: 'schema_dialect_unsupported',\n message: `unsupported JSON Schema dialect${dialect ? `: ${dialect}` : ''}; expected Draft-07 or Draft 2019-09`,\n details: { dialect },\n };\n }\n\n const keywordCount = countSchemaKeywords(schema);\n if (keywordCount > maxKeywords) {\n return {\n ok: false,\n code: 'schema_keyword_limit_exceeded',\n message: `JSON Schema keyword count ${keywordCount} exceeds limit ${maxKeywords}`,\n details: { keywordCount, maxKeywords },\n };\n }\n\n const unsafeRegex = findUnsafeRegexPattern(schema);\n if (unsafeRegex) {\n return {\n ok: false,\n code: 'budget_exceeded',\n message: 'JSON Schema regex safety budget exceeded',\n details: unsafeRegexDetails(unsafeRegex),\n };\n }\n\n const ajv = new Ajv2019({ strict: false, allErrors: true, validateSchema: true });\n addFormats(ajv);\n ajv.addMetaSchema(draft7MetaSchema);\n ajv.addMetaSchema({ ...draft7MetaSchema, $id: 'https://json-schema.org/draft-07/schema#' });\n const schemaToCompile =\n normalizedDialect === 'draft-07'\n ? { ...schema, $schema: 'http://json-schema.org/draft-07/schema#' }\n : { ...schema, $schema: 'https://json-schema.org/draft/2019-09/schema' };\n try {\n ajv.compile(schemaToCompile);\n } catch (err) {\n return {\n ok: false,\n code: 'schema_compile_failed',\n message: err instanceof Error ? err.message : String(err),\n details: { errors: ajv.errors?.slice(0, 10) ?? [] },\n };\n }\n return { ok: true };\n}\n\nexport function createCanonicalReferenceResolver(\n defaultOptions: CanonicalReferenceResolverOptions = {}\n): CanonicalReferenceResolver {\n const cache = defaultOptions.cache ?? createMemoryCanonicalReferenceCache();\n const fetchCache = createMemoryFormatSchemaCache();\n\n async function resolveReference(\n ref: FormatSchemaRef,\n options: ResolveCanonicalReferenceOptions\n ): Promise<CanonicalReferenceResolutionResult> {\n const merged: CanonicalReferenceResolverOptions = { ...defaultOptions, ...options };\n const kind = options.kind;\n const key = ref && typeof ref.uri === 'string' && typeof ref.digest === 'string' ? cacheKey(kind, ref) : undefined;\n if (key) {\n const cached = cache.get(key);\n if (cached) return cloneResolvedResult(cached, true);\n }\n\n let fetched: FormatSchemaFetchResult;\n try {\n fetched = await fetchFormatSchema(ref, toFetchOptions(merged, fetchCache));\n } catch (err) {\n if (err instanceof FormatSchemaFetchError) return mapFetchError(kind, ref ?? {}, err);\n return fail(kind, ref ?? {}, 'unresolvable', 'network_error', err instanceof Error ? err.message : String(err));\n }\n\n let document = fetched.schema;\n let refCount: number | undefined;\n let maxDepthSeen: number | undefined;\n\n if (kind === 'format_schema') {\n try {\n const resolved = await resolveSchemaRefs(document, fetched.ref.uri, {\n maxDepth: merged.maxRefDepth ?? DEFAULT_MAX_REF_DEPTH,\n maxRefCount: merged.maxRefCount ?? DEFAULT_MAX_REF_COUNT,\n mirrorHost: merged.mirrorHost,\n mirrorHosts: merged.mirrorHosts,\n timeoutMs: merged.timeoutMs,\n maxBodyBytes: merged.maxBodyBytes,\n allowInternalReferences: merged.allowInternalReferences,\n fetchExternal: merged.fetchExternal,\n });\n document = resolved.schema;\n refCount = resolved.refCount;\n maxDepthSeen = resolved.maxDepthSeen;\n } catch (err) {\n if (err instanceof SchemaRefSandboxError) return mapSandboxError(kind, fetched.ref, err);\n return fail(\n kind,\n fetched.ref,\n 'invalid_schema',\n 'fetch_failed',\n err instanceof Error ? err.message : String(err)\n );\n }\n\n const schemaValidation = validateJsonSchema(document, merged.maxKeywords ?? DEFAULT_MAX_KEYWORDS);\n if (!schemaValidation.ok) {\n return fail(kind, fetched.ref, 'invalid_schema', schemaValidation.code, schemaValidation.message, {\n details: schemaValidation.details,\n });\n }\n }\n\n const resolved: CanonicalReferenceResolvedResult = {\n ok: true,\n status: 'resolved',\n kind,\n ref: fetched.ref,\n document,\n rawDocument: fetched.schema,\n fromCache: false,\n refCount,\n maxDepthSeen,\n };\n if (key) cache.set(key, resolved);\n return cloneResolvedResult(resolved, false);\n }\n\n return {\n resolveReference,\n resolveFormatSchema(ref, options = {}) {\n return resolveReference(ref, { ...options, kind: 'format_schema' });\n },\n resolvePlatformExtension(ref, options = {}) {\n return resolveReference(ref, { ...options, kind: 'platform_extensions' });\n },\n };\n}\n\nexport async function resolveFormatSchema(\n ref: FormatSchemaRef,\n options: CanonicalReferenceResolverOptions = {}\n): Promise<CanonicalReferenceResolutionResult> {\n return createCanonicalReferenceResolver(options).resolveFormatSchema(ref);\n}\n\nexport async function resolvePlatformExtension(\n ref: FormatSchemaRef,\n options: CanonicalReferenceResolverOptions = {}\n): Promise<CanonicalReferenceResolutionResult> {\n return createCanonicalReferenceResolver(options).resolvePlatformExtension(ref);\n}\n\nexport const createCanonicalRefResolver = createCanonicalReferenceResolver;\n"],"mappings":"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","names":["resolved"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/v2/format-schema/resolver.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// 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/2019.js`. The ESM build gets a\n// `createRequire` shim, so `require` is available in both formats.\nconst Ajv2019 = require('ajv/dist/2019') as typeof import('ajv/dist/2019').default;\nimport addFormats from 'ajv-formats';\n// Loaded via `require` (not a JSON `import`) so it resolves in both CJS and\n// ESM without a Node import attribute; the ESM build gets a `createRequire`\n// shim for this module.\nconst draft7MetaSchema = require('ajv/dist/refs/json-schema-draft-07.json');\nimport {\n fetchFormatSchema,\n FormatSchemaFetchError,\n type FetchFormatSchemaOptions,\n type FormatSchemaCache,\n type FormatSchemaFetchErrorCode,\n type FormatSchemaFetchResult,\n type FormatSchemaRef,\n} from './fetch';\nimport {\n DEFAULT_MAX_KEYWORDS,\n DEFAULT_MAX_REF_COUNT,\n DEFAULT_MAX_REF_DEPTH,\n resolveSchemaRefs,\n SchemaRefSandboxError,\n type ResolveSchemaRefsOptions,\n type SchemaRefSandboxErrorCode,\n} from './sandbox-refs';\nimport { findUnsafeRegexPattern, unsafeRegexDetails } from './regex-safety';\n\nexport type CanonicalReferenceKind = 'format_schema' | 'platform_extensions';\nexport type CanonicalRef = FormatSchemaRef;\n\nexport type CanonicalReferenceResolutionStatus =\n | 'resolved'\n | 'invalid_ref'\n | 'blocked_unsafe_url'\n | 'digest_mismatch'\n | 'invalid_schema'\n | 'unresolvable';\n\nexport type CanonicalReferenceResolutionCode =\n | FormatSchemaFetchErrorCode\n | SchemaRefSandboxErrorCode\n | 'schema_dialect_unsupported'\n | 'schema_compile_failed'\n | 'schema_keyword_limit_exceeded'\n | 'budget_exceeded';\n\nexport interface CanonicalReferenceResolvedResult {\n ok: true;\n status: 'resolved';\n kind: CanonicalReferenceKind;\n ref: FormatSchemaRef;\n /**\n * Resolved document. For `format_schema`, every allowed `$ref` has\n * been inlined and the result has compiled as JSON Schema. For\n * `platform_extensions`, this is the fetched JSON object.\n */\n document: Record<string, unknown>;\n /** Original digest-verified document, before `$ref` inlining. */\n rawDocument: Record<string, unknown>;\n /** True when returned from the caller-scoped immutable cache. */\n fromCache: boolean;\n /** `format_schema` only: count of `$ref` occurrences resolved. */\n refCount?: number;\n /** `format_schema` only: deepest transitive `$ref` depth observed. */\n maxDepthSeen?: number;\n}\n\nexport interface CanonicalReferenceFailureResult {\n ok: false;\n status: Exclude<CanonicalReferenceResolutionStatus, 'resolved'>;\n kind: CanonicalReferenceKind;\n ref: Partial<FormatSchemaRef>;\n /** Stable transport/schema subreason. Same value as `code`. */\n reason: CanonicalReferenceResolutionCode;\n code: CanonicalReferenceResolutionCode;\n /** True for transient network/server/cap failures callers may retry. */\n retryable: boolean;\n message: string;\n httpStatus?: number;\n details?: Record<string, unknown>;\n}\n\nexport type CanonicalReferenceResolutionResult = CanonicalReferenceResolvedResult | CanonicalReferenceFailureResult;\n\nexport interface CanonicalReferenceCache {\n get(key: string): CanonicalReferenceResolvedResult | undefined;\n set(key: string, value: CanonicalReferenceResolvedResult): void;\n}\n\nexport interface CanonicalReferenceResolverOptions {\n timeoutMs?: number;\n maxBodyBytes?: number;\n cache?: CanonicalReferenceCache;\n maxRefDepth?: number;\n maxRefCount?: number;\n maxKeywords?: number;\n allowInternalReferences?: boolean;\n mirrorHost?: ResolveSchemaRefsOptions['mirrorHost'];\n mirrorHosts?: ResolveSchemaRefsOptions['mirrorHosts'];\n fetchExternal?: ResolveSchemaRefsOptions['fetchExternal'];\n}\n\nexport interface ResolveCanonicalReferenceOptions extends CanonicalReferenceResolverOptions {\n kind: CanonicalReferenceKind;\n}\n\nexport interface CanonicalReferenceResolver {\n resolveReference(\n ref: FormatSchemaRef,\n options: ResolveCanonicalReferenceOptions\n ): Promise<CanonicalReferenceResolutionResult>;\n resolveFormatSchema(\n ref: FormatSchemaRef,\n options?: CanonicalReferenceResolverOptions\n ): Promise<CanonicalReferenceResolutionResult>;\n resolvePlatformExtension(\n ref: FormatSchemaRef,\n options?: CanonicalReferenceResolverOptions\n ): Promise<CanonicalReferenceResolutionResult>;\n}\n\nexport function createMemoryCanonicalReferenceCache(): CanonicalReferenceCache {\n const store = new Map<string, CanonicalReferenceResolvedResult>();\n return {\n get: key => {\n const cached = store.get(key);\n return cached ? cloneResolvedResult(cached, false) : undefined;\n },\n set: (key, value) => {\n store.set(key, cloneResolvedResult(value, false));\n },\n };\n}\n\nfunction createMemoryFormatSchemaCache(): FormatSchemaCache {\n const store = new Map<string, FormatSchemaFetchResult>();\n return {\n get: key => store.get(key),\n set: (key, value) => {\n store.set(key, value);\n },\n };\n}\n\nfunction cacheKey(kind: CanonicalReferenceKind, ref: FormatSchemaRef): string {\n return `${kind}:${ref.uri}@${ref.digest}`;\n}\n\nfunction cloneJsonRecord<T extends Record<string, unknown>>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction cloneResolvedResult(\n result: CanonicalReferenceResolvedResult,\n fromCache: boolean\n): CanonicalReferenceResolvedResult {\n return {\n ...result,\n ref: { ...result.ref },\n document: cloneJsonRecord(result.document),\n rawDocument: cloneJsonRecord(result.rawDocument),\n fromCache,\n };\n}\n\nfunction toFetchOptions(\n options: CanonicalReferenceResolverOptions,\n fetchCache: FormatSchemaCache\n): FetchFormatSchemaOptions {\n return {\n timeoutMs: options.timeoutMs,\n maxBodyBytes: options.maxBodyBytes,\n allowInternalReferences: options.allowInternalReferences,\n cache: fetchCache,\n };\n}\n\nfunction fail(\n kind: CanonicalReferenceKind,\n ref: Partial<FormatSchemaRef>,\n status: CanonicalReferenceFailureResult['status'],\n code: CanonicalReferenceResolutionCode,\n message: string,\n meta: { httpStatus?: number; details?: Record<string, unknown>; retryable?: boolean } = {}\n): CanonicalReferenceFailureResult {\n return {\n ok: false,\n status,\n kind,\n ref,\n reason: code,\n code,\n retryable: meta.retryable ?? status === 'unresolvable',\n message,\n httpStatus: meta.httpStatus,\n details: meta.details,\n };\n}\n\nfunction mapFetchError(kind: CanonicalReferenceKind, ref: Partial<FormatSchemaRef>, err: FormatSchemaFetchError) {\n if (err.code === 'digest_mismatch') {\n return fail(kind, ref, 'digest_mismatch', err.code, err.message, {\n details: err.details,\n retryable: false,\n });\n }\n if (\n err.code === 'ssrf_refused' &&\n (err.details?.code === 'dns_lookup_failed' ||\n err.details?.code === 'dns_empty' ||\n err.details?.code === 'body_exceeds_limit')\n ) {\n return fail(kind, ref, 'unresolvable', err.code, err.message, {\n details: err.details,\n retryable: true,\n });\n }\n if (\n err.code === 'ssrf_refused' ||\n err.code === 'redirect_blocked' ||\n (err.code === 'invalid_ref' && /uri must use https/i.test(err.message))\n ) {\n return fail(kind, ref, 'blocked_unsafe_url', err.code, err.message, {\n httpStatus: err.httpStatus,\n details: err.details,\n retryable: false,\n });\n }\n if (err.code === 'invalid_ref') {\n return fail(kind, ref, 'invalid_ref', err.code, err.message, { details: err.details, retryable: false });\n }\n if (err.code === 'invalid_json') {\n return fail(kind, ref, 'invalid_schema', err.code, err.message, { details: err.details, retryable: false });\n }\n return fail(kind, ref, 'unresolvable', err.code, err.message, {\n httpStatus: err.httpStatus,\n details: err.details,\n retryable: true,\n });\n}\n\nfunction mapSandboxError(kind: CanonicalReferenceKind, ref: FormatSchemaRef, err: SchemaRefSandboxError) {\n if (err.code === 'fetch_failed' && err.details?.transient === true) {\n return fail(kind, ref, 'unresolvable', err.code, err.message, { details: err.details, retryable: true });\n }\n if (err.code === 'fetch_failed' && typeof err.details?.httpStatus === 'number') {\n const httpStatus = err.details.httpStatus;\n if (httpStatus >= 300 && httpStatus < 400) {\n return fail(kind, ref, 'blocked_unsafe_url', err.code, err.message, { details: err.details, retryable: false });\n }\n return fail(kind, ref, 'unresolvable', err.code, err.message, {\n details: err.details,\n retryable: httpStatus === 404 || httpStatus >= 500,\n });\n }\n const status =\n err.code === 'file_scheme_rejected' || err.code === 'cross_origin_rejected'\n ? 'blocked_unsafe_url'\n : 'invalid_schema';\n return fail(kind, ref, status, err.code, err.message, { details: err.details, retryable: false });\n}\n\nconst DRAFT_07_DIALECTS = new Set([\n 'http://json-schema.org/draft-07/schema',\n 'https://json-schema.org/draft-07/schema',\n]);\nconst DRAFT_2019_09_DIALECTS = new Set([\n 'http://json-schema.org/draft/2019-09/schema',\n 'https://json-schema.org/draft/2019-09/schema',\n]);\n\nfunction normalizeDialect(dialect: string | undefined): 'draft-07' | 'draft-2019-09' | undefined {\n if (!dialect) return 'draft-2019-09';\n const normalized = dialect.endsWith('#') ? dialect.slice(0, -1) : dialect;\n if (DRAFT_07_DIALECTS.has(normalized)) return 'draft-07';\n if (DRAFT_2019_09_DIALECTS.has(normalized)) return 'draft-2019-09';\n return undefined;\n}\n\nfunction countSchemaKeywords(node: unknown): number {\n if (node === null || typeof node !== 'object') return 0;\n if (Array.isArray(node)) return node.reduce((sum, item) => sum + countSchemaKeywords(item), 0);\n let count = 0;\n for (const value of Object.values(node as Record<string, unknown>)) {\n count += 1;\n count += countSchemaKeywords(value);\n }\n return count;\n}\n\nfunction validateJsonSchema(\n schema: Record<string, unknown>,\n maxKeywords: number\n):\n | { ok: true }\n | { ok: false; code: CanonicalReferenceResolutionCode; message: string; details?: Record<string, unknown> } {\n const dialect = typeof schema.$schema === 'string' ? schema.$schema : undefined;\n const normalizedDialect = normalizeDialect(dialect);\n if (!normalizedDialect) {\n return {\n ok: false,\n code: 'schema_dialect_unsupported',\n message: `unsupported JSON Schema dialect${dialect ? `: ${dialect}` : ''}; expected Draft-07 or Draft 2019-09`,\n details: { dialect },\n };\n }\n\n const keywordCount = countSchemaKeywords(schema);\n if (keywordCount > maxKeywords) {\n return {\n ok: false,\n code: 'schema_keyword_limit_exceeded',\n message: `JSON Schema keyword count ${keywordCount} exceeds limit ${maxKeywords}`,\n details: { keywordCount, maxKeywords },\n };\n }\n\n const unsafeRegex = findUnsafeRegexPattern(schema);\n if (unsafeRegex) {\n return {\n ok: false,\n code: 'budget_exceeded',\n message: 'JSON Schema regex safety budget exceeded',\n details: unsafeRegexDetails(unsafeRegex),\n };\n }\n\n const ajv = new Ajv2019({ strict: false, allErrors: true, validateSchema: true });\n addFormats(ajv);\n ajv.addMetaSchema(draft7MetaSchema);\n ajv.addMetaSchema({ ...draft7MetaSchema, $id: 'https://json-schema.org/draft-07/schema#' });\n const schemaToCompile =\n normalizedDialect === 'draft-07'\n ? { ...schema, $schema: 'http://json-schema.org/draft-07/schema#' }\n : { ...schema, $schema: 'https://json-schema.org/draft/2019-09/schema' };\n try {\n ajv.compile(schemaToCompile);\n } catch (err) {\n return {\n ok: false,\n code: 'schema_compile_failed',\n message: err instanceof Error ? err.message : String(err),\n details: { errors: ajv.errors?.slice(0, 10) ?? [] },\n };\n }\n return { ok: true };\n}\n\nexport function createCanonicalReferenceResolver(\n defaultOptions: CanonicalReferenceResolverOptions = {}\n): CanonicalReferenceResolver {\n const cache = defaultOptions.cache ?? createMemoryCanonicalReferenceCache();\n const fetchCache = createMemoryFormatSchemaCache();\n\n async function resolveReference(\n ref: FormatSchemaRef,\n options: ResolveCanonicalReferenceOptions\n ): Promise<CanonicalReferenceResolutionResult> {\n const merged: CanonicalReferenceResolverOptions = { ...defaultOptions, ...options };\n const kind = options.kind;\n const key = ref && typeof ref.uri === 'string' && typeof ref.digest === 'string' ? cacheKey(kind, ref) : undefined;\n if (key) {\n const cached = cache.get(key);\n if (cached) return cloneResolvedResult(cached, true);\n }\n\n let fetched: FormatSchemaFetchResult;\n try {\n fetched = await fetchFormatSchema(ref, toFetchOptions(merged, fetchCache));\n } catch (err) {\n if (err instanceof FormatSchemaFetchError) return mapFetchError(kind, ref ?? {}, err);\n return fail(kind, ref ?? {}, 'unresolvable', 'network_error', err instanceof Error ? err.message : String(err));\n }\n\n let document = fetched.schema;\n let refCount: number | undefined;\n let maxDepthSeen: number | undefined;\n\n if (kind === 'format_schema') {\n try {\n const resolved = await resolveSchemaRefs(document, fetched.ref.uri, {\n maxDepth: merged.maxRefDepth ?? DEFAULT_MAX_REF_DEPTH,\n maxRefCount: merged.maxRefCount ?? DEFAULT_MAX_REF_COUNT,\n mirrorHost: merged.mirrorHost,\n mirrorHosts: merged.mirrorHosts,\n timeoutMs: merged.timeoutMs,\n maxBodyBytes: merged.maxBodyBytes,\n allowInternalReferences: merged.allowInternalReferences,\n fetchExternal: merged.fetchExternal,\n });\n document = resolved.schema;\n refCount = resolved.refCount;\n maxDepthSeen = resolved.maxDepthSeen;\n } catch (err) {\n if (err instanceof SchemaRefSandboxError) return mapSandboxError(kind, fetched.ref, err);\n return fail(\n kind,\n fetched.ref,\n 'invalid_schema',\n 'fetch_failed',\n err instanceof Error ? err.message : String(err)\n );\n }\n\n const schemaValidation = validateJsonSchema(document, merged.maxKeywords ?? DEFAULT_MAX_KEYWORDS);\n if (!schemaValidation.ok) {\n return fail(kind, fetched.ref, 'invalid_schema', schemaValidation.code, schemaValidation.message, {\n details: schemaValidation.details,\n });\n }\n }\n\n const resolved: CanonicalReferenceResolvedResult = {\n ok: true,\n status: 'resolved',\n kind,\n ref: fetched.ref,\n document,\n rawDocument: fetched.schema,\n fromCache: false,\n refCount,\n maxDepthSeen,\n };\n if (key) cache.set(key, resolved);\n return cloneResolvedResult(resolved, false);\n }\n\n return {\n resolveReference,\n resolveFormatSchema(ref, options = {}) {\n return resolveReference(ref, { ...options, kind: 'format_schema' });\n },\n resolvePlatformExtension(ref, options = {}) {\n return resolveReference(ref, { ...options, kind: 'platform_extensions' });\n },\n };\n}\n\nexport async function resolveFormatSchema(\n ref: FormatSchemaRef,\n options: CanonicalReferenceResolverOptions = {}\n): Promise<CanonicalReferenceResolutionResult> {\n return createCanonicalReferenceResolver(options).resolveFormatSchema(ref);\n}\n\nexport async function resolvePlatformExtension(\n ref: FormatSchemaRef,\n options: CanonicalReferenceResolverOptions = {}\n): Promise<CanonicalReferenceResolutionResult> {\n return createCanonicalReferenceResolver(options).resolvePlatformExtension(ref);\n}\n\nexport const createCanonicalRefResolver = createCanonicalReferenceResolver;\n"],"mappings":"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","names":["require","resolved"]}
|
|
@@ -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 { ssrfSafeFetch, SsrfRefusedError } from "../../net/ssrf-fetch.mjs";
|
|
8
2
|
import { isInternalProbesAllowed } from "../../utils/probe-policy.mjs";
|
|
9
3
|
class SchemaRefSandboxError extends Error {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/v2/format-schema/sandbox-refs.ts"],"sourcesContent":["/**\n * `$ref` sandboxing + DoS bounds for `format_schema` JSON Schema bodies.\n *\n * Implements the spec's normative rules from\n * `product-format-declaration.json#format_schema`:\n *\n * - **Sandboxing**: fetched schemas MAY use `$ref`. Refs MUST resolve\n * only to one of three forms:\n * (a) same-origin as the parent `format_schema.uri` after\n * RFC 3986 ยง6 normalization (lowercase scheme + host, strip\n * default port, normalize path dot-segments, no userinfo),\n * (b) under the AAO mirror namespace\n * (`https://creative.adcontextprotocol.org/...` โ\n * legacy `mirror.adcontextprotocol.org` deprecated in\n * adcontextprotocol/adcp#4866 / 3.1.0-beta.2),\n * (c) intra-document JSON Pointer refs (`#/...`) bounded to the\n * parent document's parsed tree.\n * `$ref: \"file://...\"` rejected unconditionally. Cross-origin refs\n * to arbitrary URIs rejected.\n *\n * - **Bounds**: transitive `$ref` chains MUST be bounded at\n * depth โค 8 AND `$ref` count โค 256 across the resolved tree.\n * Defaults match the spec ceiling; callers may tighten via options.\n *\n * The sandboxer takes an already-fetched + digest-verified parent\n * schema (from `fetchFormatSchema`) and inlines every reachable `$ref`.\n * External refs go through the same {@link fetchFormatSchema} pipeline\n * โ HTTPS-only, SSRF-guarded, 1 MiB body cap, 5 s timeout. The parent\n * digest is the trust anchor; same-origin / mirror refs inherit trust.\n *\n * Out of scope (deferred to the manifest-validation layer):\n * - Schema-compile DoS bounds (re2 pattern engine, allOf expansion,\n * per-manifest validation budget โค 250 ms) โ applied at the Ajv\n * compile step. The constants {@link DEFAULT_MAX_KEYWORDS} and\n * {@link DEFAULT_VALIDATION_BUDGET_MS} are exported here so the\n * Ajv wiring can pick them up.\n */\n\nimport { ssrfSafeFetch, SsrfRefusedError } from '../../net/ssrf-fetch';\nimport { isInternalProbesAllowed } from '../../utils/probe-policy';\n\n/**\n * Error codes from {@link resolveSchemaRefs}. Mirror the spec's\n * normative failure modes so SDK callers can surface them on the\n * response `errors[]` array.\n */\nexport type SchemaRefSandboxErrorCode =\n /** `$ref` value isn't a string or fails basic URL parsing. */\n | 'invalid_ref'\n /** `$ref: \"file://...\"` is unconditionally rejected. */\n | 'file_scheme_rejected'\n /** Cross-origin `$ref` to a URI not in the same-origin / mirror allowlist. */\n | 'cross_origin_rejected'\n /** Intra-doc `#/...` pointer doesn't resolve. */\n | 'pointer_unresolved'\n /** Transitive depth exceeded the per-call limit. */\n | 'depth_exceeded'\n /** Total `$ref` count exceeded the per-call limit. */\n | 'count_exceeded'\n /** Downstream `fetchFormatSchema` rejected โ message carries the wrapped error code. */\n | 'fetch_failed';\n\nexport class SchemaRefSandboxError extends Error {\n readonly code: SchemaRefSandboxErrorCode;\n readonly ref?: string;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: SchemaRefSandboxErrorCode,\n message: string,\n meta: { ref?: string; details?: Record<string, unknown> } = {}\n ) {\n super(message);\n this.name = 'SchemaRefSandboxError';\n this.code = code;\n this.ref = meta.ref;\n this.details = meta.details;\n }\n}\n\nexport interface ResolveSchemaRefsOptions {\n /**\n * Max transitive `$ref` depth before failing. Default 8 (spec ceiling).\n */\n maxDepth?: number;\n /**\n * Max total `$ref` occurrences across the resolved tree before failing.\n * Default 256 (spec ceiling).\n */\n maxRefCount?: number;\n /**\n * Single AAO mirror host that `$ref` targets are allowed to live under.\n * Convenience for `mirrorHosts: [host]`; ignored when `mirrorHosts`\n * is also set. Not deprecated โ it's a narrowing of the array form,\n * useful for callers who genuinely have a single-host allowlist (the\n * common case during the transitional period). Pick `mirrorHost` for\n * single-host, `mirrorHosts` for multi-host or future-proofing.\n */\n mirrorHost?: string;\n /**\n * AAO mirror hosts that `$ref` targets are allowed to live under.\n * Defaults to {@link DEFAULT_MIRROR_HOSTS} โ\n * `['creative.adcontextprotocol.org']` at 3.1.0-beta.2+. The legacy\n * `mirror.adcontextprotocol.org` anchor was deprecated in\n * adcontextprotocol/adcp#4866 (never provisioned). Override when\n * running against a stand-in mirror in tests.\n */\n mirrorHosts?: readonly string[];\n /**\n * Per-fetch timeout (ms) for each external `$ref`. Default 5 s\n * โ same as the parent format_schema fetch.\n */\n timeoutMs?: number;\n /**\n * Hard cap on response body bytes per `$ref` fetch. Default 1 MiB.\n */\n maxBodyBytes?: number;\n /**\n * Caller-scoped test/dev opt-in for loopback/private HTTP `$ref`\n * fetches. Production callers should leave this false. IMDS/link-local\n * metadata endpoints remain blocked by `ssrfSafeFetch`.\n */\n allowInternalReferences?: boolean;\n /**\n * Optional custom fetcher for external `$ref` URIs. Defaults to a\n * built-in that uses `ssrfSafeFetch` with HTTPS-only + 1 MiB cap +\n * 5 s timeout. Callers can swap this for a digest-enforcing variant\n * when they have an out-of-band trust signal (e.g., a registry of\n * `uri@digest` pairs).\n */\n fetchExternal?: (uri: string) => Promise<Record<string, unknown>>;\n}\n\nexport interface ResolveSchemaRefsResult {\n /**\n * The parent schema with every `$ref` recursively inlined. The\n * structure mirrors the input; nodes that originally held `$ref` now\n * hold the referenced sub-schema.\n */\n schema: Record<string, unknown>;\n /** Number of `$ref` occurrences resolved while walking the tree. */\n refCount: number;\n /** Max transitive depth observed during the walk. */\n maxDepthSeen: number;\n}\n\n/** Spec ceiling for `$ref` depth (transitive). */\nexport const DEFAULT_MAX_REF_DEPTH = 8;\n/** Spec ceiling for total `$ref` count across the resolved tree. */\nexport const DEFAULT_MAX_REF_COUNT = 256;\n/**\n * Spec-normative AAO mirror trust anchor for `$ref` resolution\n * (`product-format-declaration.json#format_schema`, post-beta.2). The\n * legacy `mirror.adcontextprotocol.org` host was deprecated in\n * adcontextprotocol/adcp#4866 (3.1.0-beta.2) โ it was never\n * provisioned and authorizing a ghost hostname is liability with no\n * upside. `creative.adcontextprotocol.org` is the single trust anchor\n * going forward.\n */\nexport const DEFAULT_MIRROR_HOSTS: readonly string[] = ['creative.adcontextprotocol.org'];\n\n/**\n * Single-host narrowing of {@link DEFAULT_MIRROR_HOSTS} for callers\n * that have a single-host allowlist (the common case at 3.1.0-beta.2+).\n * Resolves to the first host. Not deprecated โ same posture as\n * {@link ResolveSchemaRefsOptions.mirrorHost}: narrowing of the array\n * form, not a removal target.\n */\nexport const DEFAULT_MIRROR_HOST = DEFAULT_MIRROR_HOSTS[0]!;\n\n/**\n * Sibling keys that may appear alongside `$ref` and merge over the\n * resolved body. Per JSON Schema 2020-12, `$ref` siblings are an\n * *additional* constraint (conjunction with the referenced subschema),\n * NOT an override. Allowing constraint keywords (`type`, `required`,\n * `additionalProperties`, etc.) to override the referent silently\n * defangs the referenced subschema's guarantees โ a malicious or\n * sloppy author can flip `additionalProperties: false` to `true` and\n * smuggle unvalidated fields through manifest validation.\n *\n * This allowlist permits annotation-only siblings (description, title,\n * comments, examples, defaults, deprecation flags) โ fields that don't\n * affect what validates. Constraint keywords on `$ref` are rejected as\n * `invalid_ref` so authors are forced to inline the constraint.\n */\nconst ALLOWED_REF_SIBLINGS = new Set<string>([\n '$comment',\n '$schema',\n 'default',\n 'deprecated',\n 'description',\n 'examples',\n 'readOnly',\n 'title',\n 'writeOnly',\n]);\n\n/**\n * JSON Pointer segments that are NEVER allowed on `$ref: \"#/...\"`\n * targets. `__proto__` / `constructor` / `prototype` are the standard\n * prototype-pollution sinks; we reject them up front so a malicious\n * (or accidentally-crafted) intra-doc pointer can't drag the prototype\n * chain into the resolved schema and have downstream Ajv merges land\n * on `Object.prototype`.\n */\nconst FORBIDDEN_POINTER_SEGMENTS = new Set<string>(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Spec-recommended bound on Ajv-compiled keyword count. Applied by the\n * manifest validator, not by the sandboxer โ exported here so the Ajv\n * wiring has a single source of truth.\n */\nexport const DEFAULT_MAX_KEYWORDS = 10_000;\n\n/**\n * Spec-recommended per-manifest validation budget in milliseconds.\n * Exceeded budget โ treat manifest as invalid + surface telemetry signal.\n */\nexport const DEFAULT_VALIDATION_BUDGET_MS = 250;\n\ninterface NormalizedOrigin {\n /** Lowercase scheme + `://` + lowercase host + (port if non-default). */\n origin: string;\n /** Hostname only, lowercased. */\n hostname: string;\n}\n\n/**\n * RFC 3986 ยง6 normalization of a URI's origin: lowercase scheme + host,\n * strip default port, no userinfo. Returns `null` for unparseable URIs.\n */\nfunction normalizeOrigin(uri: string): NormalizedOrigin | null {\n let parsed: URL;\n try {\n parsed = new URL(uri);\n } catch {\n return null;\n }\n const scheme = parsed.protocol.toLowerCase();\n const hostname = parsed.hostname.toLowerCase();\n const defaultPorts: Record<string, string> = { 'http:': '80', 'https:': '443' };\n const port = parsed.port && parsed.port !== defaultPorts[scheme] ? `:${parsed.port}` : '';\n return {\n origin: `${scheme}//${hostname}${port}`,\n hostname,\n };\n}\n\n/**\n * Resolve a JSON Pointer (`#/foo/bar`) against the parent document's\n * parsed tree. Returns the referenced subtree, or `null` when the\n * pointer doesn't resolve.\n */\nfunction resolveJsonPointer(root: Record<string, unknown>, pointer: string): unknown | null {\n // RFC 6901: empty pointer (`#` alone) returns the root document.\n if (pointer === '') return root;\n // Drop the leading slash; split; decode per RFC 6901 (~1 โ /, ~0 โ ~).\n const segments = pointer\n .replace(/^\\//, '')\n .split('/')\n .map(s => s.replace(/~1/g, '/').replace(/~0/g, '~'));\n let cursor: unknown = root;\n for (const seg of segments) {\n // Reject prototype-pollution segments up front. `JSON.parse`-produced\n // objects can carry an OWN `__proto__` property (V8 quirk), so\n // `hasOwnProperty` alone doesn't block the attack path โ we also\n // need to refuse the segment name unconditionally.\n if (FORBIDDEN_POINTER_SEGMENTS.has(seg)) return null;\n if (cursor === null || typeof cursor !== 'object') return null;\n if (Array.isArray(cursor)) {\n const idx = Number(seg);\n if (!Number.isInteger(idx) || idx < 0 || idx >= cursor.length) return null;\n cursor = cursor[idx];\n } else {\n const obj = cursor as Record<string, unknown>;\n if (!Object.prototype.hasOwnProperty.call(obj, seg)) return null;\n cursor = obj[seg];\n }\n }\n return cursor;\n}\n\ninterface ResolveContext {\n parentRoot: Record<string, unknown>;\n currentUri: string;\n parentOrigin: NormalizedOrigin;\n /** Lowercased AAO mirror hosts that are accepted as `$ref` targets. */\n mirrorHosts: ReadonlySet<string>;\n maxDepth: number;\n maxRefCount: number;\n fetchExternal: (uri: string) => Promise<Record<string, unknown>>;\n /** Per-resolved-URI cache so cycles + repeats don't fan out repeatedly. */\n externalCache: Map<string, Record<string, unknown>>;\n /** Running count of `$ref` occurrences across the whole walk. */\n count: { value: number };\n /** Running max-depth observed (for telemetry). */\n maxDepthSeen: { value: number };\n}\n\n/**\n * Default external-`$ref` fetcher. Uses `ssrfSafeFetch` for HTTPS-only +\n * SSRF guards + body cap + timeout. No per-`$ref` digest verification โ\n * the parent format_schema's digest is the trust anchor; same-origin\n * and mirror `$ref` targets inherit trust by extension. Callers wanting\n * per-`$ref` digests pass a custom `fetchExternal` (e.g., a registry\n * lookup that hard-fails on missing digests).\n */\nfunction makeDefaultFetcher(\n timeoutMs: number,\n maxBodyBytes: number,\n allowInternalReferences: boolean\n): (uri: string) => Promise<Record<string, unknown>> {\n const allowHttp = allowInternalReferences || isInternalProbesAllowed();\n return async (uri: string) => {\n let res;\n try {\n res = await ssrfSafeFetch(uri, {\n method: 'GET',\n timeoutMs,\n maxBodyBytes,\n headers: { accept: 'application/schema+json, application/json' },\n allowPrivateIp: allowHttp,\n });\n } catch (err) {\n if (err instanceof SsrfRefusedError) {\n const isTransient =\n err.code === 'dns_lookup_failed' || err.code === 'dns_empty' || err.code === 'body_exceeds_limit';\n throw new SchemaRefSandboxError('fetch_failed', `\\`$ref: ${uri}\\` โ SSRF guard refused: ${err.message}`, {\n ref: uri,\n details: { ssrfCode: err.code, transient: isTransient },\n });\n }\n throw new SchemaRefSandboxError(\n 'fetch_failed',\n `\\`$ref: ${uri}\\` โ ${err instanceof Error ? err.message : String(err)}`,\n { ref: uri, details: { transient: true } }\n );\n }\n if (res.status >= 300 && res.status < 400) {\n throw new SchemaRefSandboxError(\n 'fetch_failed',\n `\\`$ref: ${uri}\\` โ HTTP redirect ${res.status} (auto-follow disabled)`,\n {\n ref: uri,\n details: { httpStatus: res.status },\n }\n );\n }\n if (res.status < 200 || res.status >= 300) {\n throw new SchemaRefSandboxError('fetch_failed', `\\`$ref: ${uri}\\` โ HTTP ${res.status}`, {\n ref: uri,\n details: { httpStatus: res.status, transient: res.status >= 500 },\n });\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(new TextDecoder('utf-8').decode(res.body));\n } catch (err) {\n throw new SchemaRefSandboxError(\n 'fetch_failed',\n `\\`$ref: ${uri}\\` โ body is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n { ref: uri }\n );\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new SchemaRefSandboxError('fetch_failed', `\\`$ref: ${uri}\\` โ body is not a JSON object`, { ref: uri });\n }\n return parsed as Record<string, unknown>;\n };\n}\n\n/**\n * Validate that an external (non-`#/`) `$ref` target is in the\n * allowed set: same-origin as parent OR under the AAO mirror namespace.\n * Returns the absolute target URI on success; throws otherwise.\n */\nfunction assertRefAllowed(ref: string, ctx: ResolveContext): string {\n if (ref.toLowerCase().startsWith('file:')) {\n throw new SchemaRefSandboxError(\n 'file_scheme_rejected',\n `\\`$ref: ${ref}\\` โ file:// scheme rejected unconditionally`,\n {\n ref,\n }\n );\n }\n let targetUri: string;\n try {\n targetUri = new URL(ref, ctx.currentUri).href;\n } catch {\n throw new SchemaRefSandboxError('invalid_ref', `\\`$ref: ${ref}\\` โ could not parse as a URI`, { ref });\n }\n const target = normalizeOrigin(targetUri);\n if (!target) {\n throw new SchemaRefSandboxError('invalid_ref', `\\`$ref: ${ref}\\` โ could not parse as a URI`, { ref });\n }\n // Same-origin?\n if (target.origin === ctx.parentOrigin.origin) {\n return targetUri;\n }\n // AAO mirror namespace? Spec is `https://` only โ `http://` mirror\n // refs are rejected even when the host matches.\n if (ctx.mirrorHosts.has(target.hostname) && targetUri.toLowerCase().startsWith('https://')) {\n return targetUri;\n }\n const mirrorList = [...ctx.mirrorHosts].join(', ');\n throw new SchemaRefSandboxError(\n 'cross_origin_rejected',\n `\\`$ref: ${ref}\\` โ not same-origin as parent (${ctx.parentOrigin.origin}) and not under an AAO mirror (${mirrorList})`,\n { ref, details: { parentOrigin: ctx.parentOrigin.origin, targetOrigin: target.origin } }\n );\n}\n\n/**\n * Walk a schema subtree, resolving every `$ref` inline. Recursive โ\n * each external fetch's body is walked again under the new origin\n * context (depth increments).\n */\nasync function walk(node: unknown, depth: number, ctx: ResolveContext): Promise<unknown> {\n if (depth > ctx.maxDepthSeen.value) ctx.maxDepthSeen.value = depth;\n if (depth > ctx.maxDepth) {\n throw new SchemaRefSandboxError(\n 'depth_exceeded',\n `\\`$ref\\` transitive depth exceeded ${ctx.maxDepth} (spec ceiling)`,\n { details: { maxDepth: ctx.maxDepth, depthSeen: depth } }\n );\n }\n if (node === null || typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n const out: unknown[] = [];\n for (const item of node) out.push(await walk(item, depth, ctx));\n return out;\n }\n const obj = node as Record<string, unknown>;\n // $ref node: resolve it inline. Sibling keys are restricted to the\n // annotation-only allowlist (description / title / examples / etc.) โ\n // constraint keywords (`type`, `required`, `additionalProperties`,\n // `properties`, `items`, ...) on a `$ref` node would silently override\n // the referenced subschema's guarantees and defang manifest\n // validation. Per JSON Schema 2020-12 `$ref` siblings are an\n // additional constraint, not an override; we surface the constraint\n // mismatch as `invalid_ref` so authors must inline rather than smuggle.\n if (typeof obj.$ref === 'string') {\n ctx.count.value += 1;\n if (ctx.count.value > ctx.maxRefCount) {\n throw new SchemaRefSandboxError(\n 'count_exceeded',\n `\\`$ref\\` count exceeded ${ctx.maxRefCount} across the resolved tree (spec ceiling)`,\n { details: { maxRefCount: ctx.maxRefCount, count: ctx.count.value } }\n );\n }\n const ref = obj.$ref;\n const { $ref: _drop, ...rest } = obj;\n void _drop;\n const disallowed = Object.keys(rest).filter(k => !ALLOWED_REF_SIBLINGS.has(k));\n if (disallowed.length > 0) {\n throw new SchemaRefSandboxError(\n 'invalid_ref',\n `\\`$ref: ${ref}\\` has disallowed sibling keys [${disallowed.join(', ')}]; ` +\n `only annotation siblings (${[...ALLOWED_REF_SIBLINGS].sort().join(', ')}) ` +\n `may appear alongside a $ref. Inline the constraint instead.`,\n { ref, details: { disallowedSiblings: disallowed } }\n );\n }\n let resolved: Record<string, unknown>;\n if (ref.startsWith('#')) {\n // Intra-document pointer. Resolve against the parent root.\n const pointer = ref.slice(1);\n const target = resolveJsonPointer(ctx.parentRoot, pointer);\n if (target === null) {\n throw new SchemaRefSandboxError(\n 'pointer_unresolved',\n `\\`$ref: ${ref}\\` โ pointer not resolved in parent document`,\n {\n ref,\n }\n );\n }\n // Walk the resolved subtree at the same depth โ same-document\n // pointers don't introduce a new origin layer; only count toward\n // the global count limit. Intra-doc pointer chains do hit the\n // depth cap if they're cyclic, which protects against\n // `#/a -> #/b -> #/a` loops.\n resolved = (await walk(target, depth + 1, ctx)) as Record<string, unknown>;\n } else {\n // External ref. Validate origin, fetch, walk the fetched body.\n // Parent digest is the trust anchor; same-origin / mirror refs\n // inherit trust. Callers wanting per-`$ref` digest verification\n // pass a custom `fetchExternal` that enforces it.\n const refUri = assertRefAllowed(ref, ctx);\n let body: Record<string, unknown>;\n const cached = ctx.externalCache.get(refUri);\n if (cached) {\n body = cached;\n } else {\n try {\n body = await ctx.fetchExternal(refUri);\n } catch (err) {\n if (err instanceof SchemaRefSandboxError) throw err;\n throw new SchemaRefSandboxError(\n 'fetch_failed',\n `\\`$ref: ${refUri}\\` โ ${err instanceof Error ? err.message : String(err)}`,\n {\n ref: refUri,\n details: { transient: true },\n }\n );\n }\n ctx.externalCache.set(refUri, body);\n }\n // External fetch opens a new document layer. We treat each\n // external fetch as one depth step.\n const refCtx: ResolveContext = {\n ...ctx,\n currentUri: refUri,\n // The fetched document becomes the parent for its own intra-doc\n // pointers. Same-origin checks for its own external $refs still\n // use the ORIGINAL parent origin (the trust root). Per spec the\n // trust anchor is the top-level format_schema.uri@digest, so\n // nested same-origin checks should resolve against THAT origin,\n // not the chain's last hop โ otherwise an attacker who\n // controls one mirror-hosted schema could re-export to another\n // origin via a single redirect-like $ref.\n parentRoot: body,\n };\n resolved = (await walk(body, depth + 1, refCtx)) as Record<string, unknown>;\n }\n // Merge sibling annotations UNDER the resolved body โ referent wins\n // on key collision. With the allowlist above this is purely\n // cosmetic (no constraint keys can collide); the spread order is\n // defensive against future allowlist expansion that might admit a\n // key the referent also defines.\n return Object.keys(rest).length > 0 ? { ...rest, ...resolved } : resolved;\n }\n // Plain object โ recurse into properties.\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n out[k] = await walk(v, depth, ctx);\n }\n return out;\n}\n\n/**\n * Recursively resolve every `$ref` in a fetched format_schema body,\n * honoring the spec's sandboxing + bounds. Returns the fully-inlined\n * schema and telemetry (`refCount`, `maxDepthSeen`).\n *\n * Throws {@link SchemaRefSandboxError} on the first failure (missing\n * pointer, cross-origin ref, depth/count exceeded, downstream fetch\n * failure). Callers surface the structured code on the response\n * envelope's `errors[]` array.\n *\n * @example\n * ```ts\n * import { fetchFormatSchema, resolveSchemaRefs } from '@adcp/sdk/v2/format-schema';\n *\n * const { schema, ref } = await fetchFormatSchema(formatSchemaRef);\n * const { schema: resolved } = await resolveSchemaRefs(schema, ref.uri);\n * // Feed `resolved` to Ajv. Ajv won't try to fetch any remaining $refs\n * // because every one has been inlined.\n * ```\n */\nexport async function resolveSchemaRefs(\n schema: Record<string, unknown>,\n parentUri: string,\n options: ResolveSchemaRefsOptions = {}\n): Promise<ResolveSchemaRefsResult> {\n const parentOrigin = normalizeOrigin(parentUri);\n if (!parentOrigin) {\n throw new SchemaRefSandboxError('invalid_ref', `parent URI '${parentUri}' could not be parsed`, { ref: parentUri });\n }\n const timeoutMs = options.timeoutMs ?? 5_000;\n const maxBodyBytes = options.maxBodyBytes ?? 1024 * 1024;\n const allowInternalReferences = options.allowInternalReferences === true;\n const ctx: ResolveContext = {\n parentRoot: schema,\n currentUri: parentUri,\n parentOrigin,\n mirrorHosts: new Set(\n (options.mirrorHosts ?? (options.mirrorHost ? [options.mirrorHost] : DEFAULT_MIRROR_HOSTS)).map(h =>\n h.toLowerCase()\n )\n ),\n maxDepth: options.maxDepth ?? DEFAULT_MAX_REF_DEPTH,\n maxRefCount: options.maxRefCount ?? DEFAULT_MAX_REF_COUNT,\n fetchExternal: options.fetchExternal ?? makeDefaultFetcher(timeoutMs, maxBodyBytes, allowInternalReferences),\n externalCache: new Map(),\n count: { value: 0 },\n maxDepthSeen: { value: 0 },\n };\n const resolved = (await walk(schema, 0, ctx)) as Record<string, unknown>;\n return {\n schema: resolved,\n refCount: ctx.count.value,\n maxDepthSeen: ctx.maxDepthSeen.value,\n };\n}\n"],"mappings":"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","names":["out"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/v2/format-schema/sandbox-refs.ts"],"sourcesContent":["/**\n * `$ref` sandboxing + DoS bounds for `format_schema` JSON Schema bodies.\n *\n * Implements the spec's normative rules from\n * `product-format-declaration.json#format_schema`:\n *\n * - **Sandboxing**: fetched schemas MAY use `$ref`. Refs MUST resolve\n * only to one of three forms:\n * (a) same-origin as the parent `format_schema.uri` after\n * RFC 3986 ยง6 normalization (lowercase scheme + host, strip\n * default port, normalize path dot-segments, no userinfo),\n * (b) under the AAO mirror namespace\n * (`https://creative.adcontextprotocol.org/...` โ\n * legacy `mirror.adcontextprotocol.org` deprecated in\n * adcontextprotocol/adcp#4866 / 3.1.0-beta.2),\n * (c) intra-document JSON Pointer refs (`#/...`) bounded to the\n * parent document's parsed tree.\n * `$ref: \"file://...\"` rejected unconditionally. Cross-origin refs\n * to arbitrary URIs rejected.\n *\n * - **Bounds**: transitive `$ref` chains MUST be bounded at\n * depth โค 8 AND `$ref` count โค 256 across the resolved tree.\n * Defaults match the spec ceiling; callers may tighten via options.\n *\n * The sandboxer takes an already-fetched + digest-verified parent\n * schema (from `fetchFormatSchema`) and inlines every reachable `$ref`.\n * External refs go through the same {@link fetchFormatSchema} pipeline\n * โ HTTPS-only, SSRF-guarded, 1 MiB body cap, 5 s timeout. The parent\n * digest is the trust anchor; same-origin / mirror refs inherit trust.\n *\n * Out of scope (deferred to the manifest-validation layer):\n * - Schema-compile DoS bounds (re2 pattern engine, allOf expansion,\n * per-manifest validation budget โค 250 ms) โ applied at the Ajv\n * compile step. The constants {@link DEFAULT_MAX_KEYWORDS} and\n * {@link DEFAULT_VALIDATION_BUDGET_MS} are exported here so the\n * Ajv wiring can pick them up.\n */\n\nimport { ssrfSafeFetch, SsrfRefusedError } from '../../net/ssrf-fetch';\nimport { isInternalProbesAllowed } from '../../utils/probe-policy';\n\n/**\n * Error codes from {@link resolveSchemaRefs}. Mirror the spec's\n * normative failure modes so SDK callers can surface them on the\n * response `errors[]` array.\n */\nexport type SchemaRefSandboxErrorCode =\n /** `$ref` value isn't a string or fails basic URL parsing. */\n | 'invalid_ref'\n /** `$ref: \"file://...\"` is unconditionally rejected. */\n | 'file_scheme_rejected'\n /** Cross-origin `$ref` to a URI not in the same-origin / mirror allowlist. */\n | 'cross_origin_rejected'\n /** Intra-doc `#/...` pointer doesn't resolve. */\n | 'pointer_unresolved'\n /** Transitive depth exceeded the per-call limit. */\n | 'depth_exceeded'\n /** Total `$ref` count exceeded the per-call limit. */\n | 'count_exceeded'\n /** Downstream `fetchFormatSchema` rejected โ message carries the wrapped error code. */\n | 'fetch_failed';\n\nexport class SchemaRefSandboxError extends Error {\n readonly code: SchemaRefSandboxErrorCode;\n readonly ref?: string;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: SchemaRefSandboxErrorCode,\n message: string,\n meta: { ref?: string; details?: Record<string, unknown> } = {}\n ) {\n super(message);\n this.name = 'SchemaRefSandboxError';\n this.code = code;\n this.ref = meta.ref;\n this.details = meta.details;\n }\n}\n\nexport interface ResolveSchemaRefsOptions {\n /**\n * Max transitive `$ref` depth before failing. Default 8 (spec ceiling).\n */\n maxDepth?: number;\n /**\n * Max total `$ref` occurrences across the resolved tree before failing.\n * Default 256 (spec ceiling).\n */\n maxRefCount?: number;\n /**\n * Single AAO mirror host that `$ref` targets are allowed to live under.\n * Convenience for `mirrorHosts: [host]`; ignored when `mirrorHosts`\n * is also set. Not deprecated โ it's a narrowing of the array form,\n * useful for callers who genuinely have a single-host allowlist (the\n * common case during the transitional period). Pick `mirrorHost` for\n * single-host, `mirrorHosts` for multi-host or future-proofing.\n */\n mirrorHost?: string;\n /**\n * AAO mirror hosts that `$ref` targets are allowed to live under.\n * Defaults to {@link DEFAULT_MIRROR_HOSTS} โ\n * `['creative.adcontextprotocol.org']` at 3.1.0-beta.2+. The legacy\n * `mirror.adcontextprotocol.org` anchor was deprecated in\n * adcontextprotocol/adcp#4866 (never provisioned). Override when\n * running against a stand-in mirror in tests.\n */\n mirrorHosts?: readonly string[];\n /**\n * Per-fetch timeout (ms) for each external `$ref`. Default 5 s\n * โ same as the parent format_schema fetch.\n */\n timeoutMs?: number;\n /**\n * Hard cap on response body bytes per `$ref` fetch. Default 1 MiB.\n */\n maxBodyBytes?: number;\n /**\n * Caller-scoped test/dev opt-in for loopback/private HTTP `$ref`\n * fetches. Production callers should leave this false. IMDS/link-local\n * metadata endpoints remain blocked by `ssrfSafeFetch`.\n */\n allowInternalReferences?: boolean;\n /**\n * Optional custom fetcher for external `$ref` URIs. Defaults to a\n * built-in that uses `ssrfSafeFetch` with HTTPS-only + 1 MiB cap +\n * 5 s timeout. Callers can swap this for a digest-enforcing variant\n * when they have an out-of-band trust signal (e.g., a registry of\n * `uri@digest` pairs).\n */\n fetchExternal?: (uri: string) => Promise<Record<string, unknown>>;\n}\n\nexport interface ResolveSchemaRefsResult {\n /**\n * The parent schema with every `$ref` recursively inlined. The\n * structure mirrors the input; nodes that originally held `$ref` now\n * hold the referenced sub-schema.\n */\n schema: Record<string, unknown>;\n /** Number of `$ref` occurrences resolved while walking the tree. */\n refCount: number;\n /** Max transitive depth observed during the walk. */\n maxDepthSeen: number;\n}\n\n/** Spec ceiling for `$ref` depth (transitive). */\nexport const DEFAULT_MAX_REF_DEPTH = 8;\n/** Spec ceiling for total `$ref` count across the resolved tree. */\nexport const DEFAULT_MAX_REF_COUNT = 256;\n/**\n * Spec-normative AAO mirror trust anchor for `$ref` resolution\n * (`product-format-declaration.json#format_schema`, post-beta.2). The\n * legacy `mirror.adcontextprotocol.org` host was deprecated in\n * adcontextprotocol/adcp#4866 (3.1.0-beta.2) โ it was never\n * provisioned and authorizing a ghost hostname is liability with no\n * upside. `creative.adcontextprotocol.org` is the single trust anchor\n * going forward.\n */\nexport const DEFAULT_MIRROR_HOSTS: readonly string[] = ['creative.adcontextprotocol.org'];\n\n/**\n * Single-host narrowing of {@link DEFAULT_MIRROR_HOSTS} for callers\n * that have a single-host allowlist (the common case at 3.1.0-beta.2+).\n * Resolves to the first host. Not deprecated โ same posture as\n * {@link ResolveSchemaRefsOptions.mirrorHost}: narrowing of the array\n * form, not a removal target.\n */\nexport const DEFAULT_MIRROR_HOST = DEFAULT_MIRROR_HOSTS[0]!;\n\n/**\n * Sibling keys that may appear alongside `$ref` and merge over the\n * resolved body. Per JSON Schema 2020-12, `$ref` siblings are an\n * *additional* constraint (conjunction with the referenced subschema),\n * NOT an override. Allowing constraint keywords (`type`, `required`,\n * `additionalProperties`, etc.) to override the referent silently\n * defangs the referenced subschema's guarantees โ a malicious or\n * sloppy author can flip `additionalProperties: false` to `true` and\n * smuggle unvalidated fields through manifest validation.\n *\n * This allowlist permits annotation-only siblings (description, title,\n * comments, examples, defaults, deprecation flags) โ fields that don't\n * affect what validates. Constraint keywords on `$ref` are rejected as\n * `invalid_ref` so authors are forced to inline the constraint.\n */\nconst ALLOWED_REF_SIBLINGS = new Set<string>([\n '$comment',\n '$schema',\n 'default',\n 'deprecated',\n 'description',\n 'examples',\n 'readOnly',\n 'title',\n 'writeOnly',\n]);\n\n/**\n * JSON Pointer segments that are NEVER allowed on `$ref: \"#/...\"`\n * targets. `__proto__` / `constructor` / `prototype` are the standard\n * prototype-pollution sinks; we reject them up front so a malicious\n * (or accidentally-crafted) intra-doc pointer can't drag the prototype\n * chain into the resolved schema and have downstream Ajv merges land\n * on `Object.prototype`.\n */\nconst FORBIDDEN_POINTER_SEGMENTS = new Set<string>(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Spec-recommended bound on Ajv-compiled keyword count. Applied by the\n * manifest validator, not by the sandboxer โ exported here so the Ajv\n * wiring has a single source of truth.\n */\nexport const DEFAULT_MAX_KEYWORDS = 10_000;\n\n/**\n * Spec-recommended per-manifest validation budget in milliseconds.\n * Exceeded budget โ treat manifest as invalid + surface telemetry signal.\n */\nexport const DEFAULT_VALIDATION_BUDGET_MS = 250;\n\ninterface NormalizedOrigin {\n /** Lowercase scheme + `://` + lowercase host + (port if non-default). */\n origin: string;\n /** Hostname only, lowercased. */\n hostname: string;\n}\n\n/**\n * RFC 3986 ยง6 normalization of a URI's origin: lowercase scheme + host,\n * strip default port, no userinfo. Returns `null` for unparseable URIs.\n */\nfunction normalizeOrigin(uri: string): NormalizedOrigin | null {\n let parsed: URL;\n try {\n parsed = new URL(uri);\n } catch {\n return null;\n }\n const scheme = parsed.protocol.toLowerCase();\n const hostname = parsed.hostname.toLowerCase();\n const defaultPorts: Record<string, string> = { 'http:': '80', 'https:': '443' };\n const port = parsed.port && parsed.port !== defaultPorts[scheme] ? `:${parsed.port}` : '';\n return {\n origin: `${scheme}//${hostname}${port}`,\n hostname,\n };\n}\n\n/**\n * Resolve a JSON Pointer (`#/foo/bar`) against the parent document's\n * parsed tree. Returns the referenced subtree, or `null` when the\n * pointer doesn't resolve.\n */\nfunction resolveJsonPointer(root: Record<string, unknown>, pointer: string): unknown | null {\n // RFC 6901: empty pointer (`#` alone) returns the root document.\n if (pointer === '') return root;\n // Drop the leading slash; split; decode per RFC 6901 (~1 โ /, ~0 โ ~).\n const segments = pointer\n .replace(/^\\//, '')\n .split('/')\n .map(s => s.replace(/~1/g, '/').replace(/~0/g, '~'));\n let cursor: unknown = root;\n for (const seg of segments) {\n // Reject prototype-pollution segments up front. `JSON.parse`-produced\n // objects can carry an OWN `__proto__` property (V8 quirk), so\n // `hasOwnProperty` alone doesn't block the attack path โ we also\n // need to refuse the segment name unconditionally.\n if (FORBIDDEN_POINTER_SEGMENTS.has(seg)) return null;\n if (cursor === null || typeof cursor !== 'object') return null;\n if (Array.isArray(cursor)) {\n const idx = Number(seg);\n if (!Number.isInteger(idx) || idx < 0 || idx >= cursor.length) return null;\n cursor = cursor[idx];\n } else {\n const obj = cursor as Record<string, unknown>;\n if (!Object.prototype.hasOwnProperty.call(obj, seg)) return null;\n cursor = obj[seg];\n }\n }\n return cursor;\n}\n\ninterface ResolveContext {\n parentRoot: Record<string, unknown>;\n currentUri: string;\n parentOrigin: NormalizedOrigin;\n /** Lowercased AAO mirror hosts that are accepted as `$ref` targets. */\n mirrorHosts: ReadonlySet<string>;\n maxDepth: number;\n maxRefCount: number;\n fetchExternal: (uri: string) => Promise<Record<string, unknown>>;\n /** Per-resolved-URI cache so cycles + repeats don't fan out repeatedly. */\n externalCache: Map<string, Record<string, unknown>>;\n /** Running count of `$ref` occurrences across the whole walk. */\n count: { value: number };\n /** Running max-depth observed (for telemetry). */\n maxDepthSeen: { value: number };\n}\n\n/**\n * Default external-`$ref` fetcher. Uses `ssrfSafeFetch` for HTTPS-only +\n * SSRF guards + body cap + timeout. No per-`$ref` digest verification โ\n * the parent format_schema's digest is the trust anchor; same-origin\n * and mirror `$ref` targets inherit trust by extension. Callers wanting\n * per-`$ref` digests pass a custom `fetchExternal` (e.g., a registry\n * lookup that hard-fails on missing digests).\n */\nfunction makeDefaultFetcher(\n timeoutMs: number,\n maxBodyBytes: number,\n allowInternalReferences: boolean\n): (uri: string) => Promise<Record<string, unknown>> {\n const allowHttp = allowInternalReferences || isInternalProbesAllowed();\n return async (uri: string) => {\n let res;\n try {\n res = await ssrfSafeFetch(uri, {\n method: 'GET',\n timeoutMs,\n maxBodyBytes,\n headers: { accept: 'application/schema+json, application/json' },\n allowPrivateIp: allowHttp,\n });\n } catch (err) {\n if (err instanceof SsrfRefusedError) {\n const isTransient =\n err.code === 'dns_lookup_failed' || err.code === 'dns_empty' || err.code === 'body_exceeds_limit';\n throw new SchemaRefSandboxError('fetch_failed', `\\`$ref: ${uri}\\` โ SSRF guard refused: ${err.message}`, {\n ref: uri,\n details: { ssrfCode: err.code, transient: isTransient },\n });\n }\n throw new SchemaRefSandboxError(\n 'fetch_failed',\n `\\`$ref: ${uri}\\` โ ${err instanceof Error ? err.message : String(err)}`,\n { ref: uri, details: { transient: true } }\n );\n }\n if (res.status >= 300 && res.status < 400) {\n throw new SchemaRefSandboxError(\n 'fetch_failed',\n `\\`$ref: ${uri}\\` โ HTTP redirect ${res.status} (auto-follow disabled)`,\n {\n ref: uri,\n details: { httpStatus: res.status },\n }\n );\n }\n if (res.status < 200 || res.status >= 300) {\n throw new SchemaRefSandboxError('fetch_failed', `\\`$ref: ${uri}\\` โ HTTP ${res.status}`, {\n ref: uri,\n details: { httpStatus: res.status, transient: res.status >= 500 },\n });\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(new TextDecoder('utf-8').decode(res.body));\n } catch (err) {\n throw new SchemaRefSandboxError(\n 'fetch_failed',\n `\\`$ref: ${uri}\\` โ body is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n { ref: uri }\n );\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new SchemaRefSandboxError('fetch_failed', `\\`$ref: ${uri}\\` โ body is not a JSON object`, { ref: uri });\n }\n return parsed as Record<string, unknown>;\n };\n}\n\n/**\n * Validate that an external (non-`#/`) `$ref` target is in the\n * allowed set: same-origin as parent OR under the AAO mirror namespace.\n * Returns the absolute target URI on success; throws otherwise.\n */\nfunction assertRefAllowed(ref: string, ctx: ResolveContext): string {\n if (ref.toLowerCase().startsWith('file:')) {\n throw new SchemaRefSandboxError(\n 'file_scheme_rejected',\n `\\`$ref: ${ref}\\` โ file:// scheme rejected unconditionally`,\n {\n ref,\n }\n );\n }\n let targetUri: string;\n try {\n targetUri = new URL(ref, ctx.currentUri).href;\n } catch {\n throw new SchemaRefSandboxError('invalid_ref', `\\`$ref: ${ref}\\` โ could not parse as a URI`, { ref });\n }\n const target = normalizeOrigin(targetUri);\n if (!target) {\n throw new SchemaRefSandboxError('invalid_ref', `\\`$ref: ${ref}\\` โ could not parse as a URI`, { ref });\n }\n // Same-origin?\n if (target.origin === ctx.parentOrigin.origin) {\n return targetUri;\n }\n // AAO mirror namespace? Spec is `https://` only โ `http://` mirror\n // refs are rejected even when the host matches.\n if (ctx.mirrorHosts.has(target.hostname) && targetUri.toLowerCase().startsWith('https://')) {\n return targetUri;\n }\n const mirrorList = [...ctx.mirrorHosts].join(', ');\n throw new SchemaRefSandboxError(\n 'cross_origin_rejected',\n `\\`$ref: ${ref}\\` โ not same-origin as parent (${ctx.parentOrigin.origin}) and not under an AAO mirror (${mirrorList})`,\n { ref, details: { parentOrigin: ctx.parentOrigin.origin, targetOrigin: target.origin } }\n );\n}\n\n/**\n * Walk a schema subtree, resolving every `$ref` inline. Recursive โ\n * each external fetch's body is walked again under the new origin\n * context (depth increments).\n */\nasync function walk(node: unknown, depth: number, ctx: ResolveContext): Promise<unknown> {\n if (depth > ctx.maxDepthSeen.value) ctx.maxDepthSeen.value = depth;\n if (depth > ctx.maxDepth) {\n throw new SchemaRefSandboxError(\n 'depth_exceeded',\n `\\`$ref\\` transitive depth exceeded ${ctx.maxDepth} (spec ceiling)`,\n { details: { maxDepth: ctx.maxDepth, depthSeen: depth } }\n );\n }\n if (node === null || typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n const out: unknown[] = [];\n for (const item of node) out.push(await walk(item, depth, ctx));\n return out;\n }\n const obj = node as Record<string, unknown>;\n // $ref node: resolve it inline. Sibling keys are restricted to the\n // annotation-only allowlist (description / title / examples / etc.) โ\n // constraint keywords (`type`, `required`, `additionalProperties`,\n // `properties`, `items`, ...) on a `$ref` node would silently override\n // the referenced subschema's guarantees and defang manifest\n // validation. Per JSON Schema 2020-12 `$ref` siblings are an\n // additional constraint, not an override; we surface the constraint\n // mismatch as `invalid_ref` so authors must inline rather than smuggle.\n if (typeof obj.$ref === 'string') {\n ctx.count.value += 1;\n if (ctx.count.value > ctx.maxRefCount) {\n throw new SchemaRefSandboxError(\n 'count_exceeded',\n `\\`$ref\\` count exceeded ${ctx.maxRefCount} across the resolved tree (spec ceiling)`,\n { details: { maxRefCount: ctx.maxRefCount, count: ctx.count.value } }\n );\n }\n const ref = obj.$ref;\n const { $ref: _drop, ...rest } = obj;\n void _drop;\n const disallowed = Object.keys(rest).filter(k => !ALLOWED_REF_SIBLINGS.has(k));\n if (disallowed.length > 0) {\n throw new SchemaRefSandboxError(\n 'invalid_ref',\n `\\`$ref: ${ref}\\` has disallowed sibling keys [${disallowed.join(', ')}]; ` +\n `only annotation siblings (${[...ALLOWED_REF_SIBLINGS].sort().join(', ')}) ` +\n `may appear alongside a $ref. Inline the constraint instead.`,\n { ref, details: { disallowedSiblings: disallowed } }\n );\n }\n let resolved: Record<string, unknown>;\n if (ref.startsWith('#')) {\n // Intra-document pointer. Resolve against the parent root.\n const pointer = ref.slice(1);\n const target = resolveJsonPointer(ctx.parentRoot, pointer);\n if (target === null) {\n throw new SchemaRefSandboxError(\n 'pointer_unresolved',\n `\\`$ref: ${ref}\\` โ pointer not resolved in parent document`,\n {\n ref,\n }\n );\n }\n // Walk the resolved subtree at the same depth โ same-document\n // pointers don't introduce a new origin layer; only count toward\n // the global count limit. Intra-doc pointer chains do hit the\n // depth cap if they're cyclic, which protects against\n // `#/a -> #/b -> #/a` loops.\n resolved = (await walk(target, depth + 1, ctx)) as Record<string, unknown>;\n } else {\n // External ref. Validate origin, fetch, walk the fetched body.\n // Parent digest is the trust anchor; same-origin / mirror refs\n // inherit trust. Callers wanting per-`$ref` digest verification\n // pass a custom `fetchExternal` that enforces it.\n const refUri = assertRefAllowed(ref, ctx);\n let body: Record<string, unknown>;\n const cached = ctx.externalCache.get(refUri);\n if (cached) {\n body = cached;\n } else {\n try {\n body = await ctx.fetchExternal(refUri);\n } catch (err) {\n if (err instanceof SchemaRefSandboxError) throw err;\n throw new SchemaRefSandboxError(\n 'fetch_failed',\n `\\`$ref: ${refUri}\\` โ ${err instanceof Error ? err.message : String(err)}`,\n {\n ref: refUri,\n details: { transient: true },\n }\n );\n }\n ctx.externalCache.set(refUri, body);\n }\n // External fetch opens a new document layer. We treat each\n // external fetch as one depth step.\n const refCtx: ResolveContext = {\n ...ctx,\n currentUri: refUri,\n // The fetched document becomes the parent for its own intra-doc\n // pointers. Same-origin checks for its own external $refs still\n // use the ORIGINAL parent origin (the trust root). Per spec the\n // trust anchor is the top-level format_schema.uri@digest, so\n // nested same-origin checks should resolve against THAT origin,\n // not the chain's last hop โ otherwise an attacker who\n // controls one mirror-hosted schema could re-export to another\n // origin via a single redirect-like $ref.\n parentRoot: body,\n };\n resolved = (await walk(body, depth + 1, refCtx)) as Record<string, unknown>;\n }\n // Merge sibling annotations UNDER the resolved body โ referent wins\n // on key collision. With the allowlist above this is purely\n // cosmetic (no constraint keys can collide); the spread order is\n // defensive against future allowlist expansion that might admit a\n // key the referent also defines.\n return Object.keys(rest).length > 0 ? { ...rest, ...resolved } : resolved;\n }\n // Plain object โ recurse into properties.\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n out[k] = await walk(v, depth, ctx);\n }\n return out;\n}\n\n/**\n * Recursively resolve every `$ref` in a fetched format_schema body,\n * honoring the spec's sandboxing + bounds. Returns the fully-inlined\n * schema and telemetry (`refCount`, `maxDepthSeen`).\n *\n * Throws {@link SchemaRefSandboxError} on the first failure (missing\n * pointer, cross-origin ref, depth/count exceeded, downstream fetch\n * failure). Callers surface the structured code on the response\n * envelope's `errors[]` array.\n *\n * @example\n * ```ts\n * import { fetchFormatSchema, resolveSchemaRefs } from '@adcp/sdk/v2/format-schema';\n *\n * const { schema, ref } = await fetchFormatSchema(formatSchemaRef);\n * const { schema: resolved } = await resolveSchemaRefs(schema, ref.uri);\n * // Feed `resolved` to Ajv. Ajv won't try to fetch any remaining $refs\n * // because every one has been inlined.\n * ```\n */\nexport async function resolveSchemaRefs(\n schema: Record<string, unknown>,\n parentUri: string,\n options: ResolveSchemaRefsOptions = {}\n): Promise<ResolveSchemaRefsResult> {\n const parentOrigin = normalizeOrigin(parentUri);\n if (!parentOrigin) {\n throw new SchemaRefSandboxError('invalid_ref', `parent URI '${parentUri}' could not be parsed`, { ref: parentUri });\n }\n const timeoutMs = options.timeoutMs ?? 5_000;\n const maxBodyBytes = options.maxBodyBytes ?? 1024 * 1024;\n const allowInternalReferences = options.allowInternalReferences === true;\n const ctx: ResolveContext = {\n parentRoot: schema,\n currentUri: parentUri,\n parentOrigin,\n mirrorHosts: new Set(\n (options.mirrorHosts ?? (options.mirrorHost ? [options.mirrorHost] : DEFAULT_MIRROR_HOSTS)).map(h =>\n h.toLowerCase()\n )\n ),\n maxDepth: options.maxDepth ?? DEFAULT_MAX_REF_DEPTH,\n maxRefCount: options.maxRefCount ?? DEFAULT_MAX_REF_COUNT,\n fetchExternal: options.fetchExternal ?? makeDefaultFetcher(timeoutMs, maxBodyBytes, allowInternalReferences),\n externalCache: new Map(),\n count: { value: 0 },\n maxDepthSeen: { value: 0 },\n };\n const resolved = (await walk(schema, 0, ctx)) as Record<string, unknown>;\n return {\n schema: resolved,\n refCount: ctx.count.value,\n maxDepthSeen: ctx.maxDepthSeen.value,\n };\n}\n"],"mappings":"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","names":["out"]}
|
|
@@ -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 { projectV1ProductToV2 } from "./v1-to-v2.mjs";
|
|
8
2
|
import { LIBRARY_VERSION } from "../../version.mjs";
|
|
9
3
|
const SDK_ID = `@adcp/sdk@${LIBRARY_VERSION}`;
|