@adcp/sdk 16.0.0-beta.7 → 16.0.0-beta.9
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/AGENTS.md +3 -3
- package/README.md +20 -0
- package/bin/adcp.js +10 -13
- package/dist/lib/conformance/index.d.mts +2 -0
- package/dist/lib/conformance/index.d.ts +2 -0
- package/dist/lib/conformance/index.js +3 -0
- package/dist/lib/conformance/index.mjs +2 -0
- package/dist/lib/conformance/property-lists.d.mts +14 -0
- package/dist/lib/conformance/property-lists.d.ts +14 -0
- package/dist/lib/conformance/property-lists.js +45 -0
- package/dist/lib/conformance/property-lists.mjs +21 -0
- package/dist/lib/conformance/runConformance.js +20 -1
- package/dist/lib/conformance/runConformance.mjs +20 -1
- package/dist/lib/conformance/types.d.mts +3 -0
- package/dist/lib/conformance/types.d.ts +3 -0
- package/dist/lib/core/AgentClient.d.mts +8 -5
- package/dist/lib/core/AgentClient.d.ts +8 -5
- package/dist/lib/core/AgentClient.js +9 -4
- package/dist/lib/core/AgentClient.mjs +9 -4
- package/dist/lib/core/SingleAgentClient.d.mts +32 -115
- package/dist/lib/core/SingleAgentClient.d.ts +32 -115
- package/dist/lib/core/SingleAgentClient.js +379 -273
- package/dist/lib/core/SingleAgentClient.mjs +387 -275
- package/dist/lib/core/TaskExecutor.d.mts +1 -16
- package/dist/lib/core/TaskExecutor.d.ts +1 -16
- package/dist/lib/core/TaskExecutor.js +34 -51
- package/dist/lib/core/TaskExecutor.mjs +12 -29
- package/dist/lib/core/product-cache.d.mts +3 -1
- package/dist/lib/core/product-cache.d.ts +3 -1
- package/dist/lib/core/product-cache.js +2 -1
- package/dist/lib/core/product-cache.mjs +2 -1
- package/dist/lib/errors/index.d.mts +2 -8
- package/dist/lib/errors/index.d.ts +2 -8
- package/dist/lib/errors/index.js +4 -4
- package/dist/lib/errors/index.mjs +4 -4
- package/dist/lib/identifiers.d.mts +53 -0
- package/dist/lib/identifiers.d.ts +53 -0
- package/dist/lib/identifiers.js +212 -0
- package/dist/lib/identifiers.mjs +163 -0
- package/dist/lib/index.d.mts +7 -5
- package/dist/lib/index.d.ts +7 -5
- package/dist/lib/index.js +2 -14
- package/dist/lib/index.mjs +1 -14
- package/dist/lib/media-buy/compatibility.d.mts +1 -1
- package/dist/lib/media-buy/compatibility.d.ts +1 -1
- package/dist/lib/media-buy/compatibility.js +26 -45
- package/dist/lib/media-buy/compatibility.mjs +26 -45
- package/dist/lib/media-buy/index.d.mts +1 -1
- package/dist/lib/media-buy/index.d.ts +1 -1
- package/dist/lib/media-buy/legacy-purchase-continuation.d.mts +2 -2
- package/dist/lib/media-buy/legacy-purchase-continuation.d.ts +2 -2
- package/dist/lib/media-buy/property-policy.d.mts +15 -1
- package/dist/lib/media-buy/property-policy.d.ts +15 -1
- package/dist/lib/media-buy/property-policy.js +135 -3
- package/dist/lib/media-buy/property-policy.mjs +134 -3
- package/dist/lib/protocols/index.js +14 -22
- package/dist/lib/protocols/index.mjs +5 -13
- package/dist/lib/registry/index.d.mts +12 -0
- package/dist/lib/registry/index.d.ts +12 -0
- package/dist/lib/registry/index.js +159 -5
- package/dist/lib/registry/index.mjs +156 -4
- package/dist/lib/registry/types.d.mts +26 -2
- package/dist/lib/registry/types.d.ts +26 -2
- package/dist/lib/registry/types.generated.d.mts +51 -11
- package/dist/lib/registry/types.generated.d.ts +51 -11
- package/dist/lib/reporting/source/conformance.d.mts +8 -8
- package/dist/lib/reporting/source/conformance.d.ts +8 -8
- package/dist/lib/reporting/source/manifest.d.mts +27 -27
- package/dist/lib/reporting/source/manifest.d.ts +27 -27
- package/dist/lib/server/create-adcp-server.js +6 -0
- package/dist/lib/server/create-adcp-server.mjs +6 -0
- package/dist/lib/server/decisioning/specialisms/lists.d.mts +4 -4
- package/dist/lib/server/decisioning/specialisms/lists.d.ts +4 -4
- package/dist/lib/server/index.d.mts +3 -0
- package/dist/lib/server/index.d.ts +3 -0
- package/dist/lib/server/index.js +8 -1
- package/dist/lib/server/index.mjs +4 -0
- package/dist/lib/server/property-lists.d.mts +36 -0
- package/dist/lib/server/property-lists.d.ts +36 -0
- package/dist/lib/server/property-lists.js +154 -0
- package/dist/lib/server/property-lists.mjs +129 -0
- package/dist/lib/server/targeting-helpers.d.mts +2 -0
- package/dist/lib/server/targeting-helpers.d.ts +2 -0
- package/dist/lib/server/targeting-helpers.js +28 -1
- package/dist/lib/server/targeting-helpers.mjs +18 -1
- package/dist/lib/signing/parser.js +2 -2
- package/dist/lib/signing/parser.mjs +2 -2
- package/dist/lib/signing/server.d.mts +1 -1
- package/dist/lib/signing/server.d.ts +1 -1
- package/dist/lib/signing/server.mjs +5 -1
- package/dist/lib/signing/webhook-verifier.d.mts +11 -0
- package/dist/lib/signing/webhook-verifier.d.ts +11 -0
- package/dist/lib/signing/webhook-verifier.js +11 -3
- package/dist/lib/signing/webhook-verifier.mjs +11 -3
- package/dist/lib/supply-path/verify.js +12 -2
- package/dist/lib/supply-path/verify.mjs +2 -2
- package/dist/lib/testing/compliance/comply.js +0 -8
- package/dist/lib/testing/compliance/comply.mjs +0 -8
- package/dist/lib/testing/compliance/storyboard-tracks.js +11 -0
- package/dist/lib/testing/compliance/storyboard-tracks.mjs +11 -0
- package/dist/lib/testing/index.d.mts +2 -0
- package/dist/lib/testing/index.d.ts +2 -0
- package/dist/lib/testing/index.js +5 -0
- package/dist/lib/testing/index.mjs +3 -0
- package/dist/lib/testing/scenarios/capabilities.d.mts +2 -2
- package/dist/lib/testing/scenarios/capabilities.d.ts +2 -2
- package/dist/lib/testing/scenarios/capabilities.js +8 -41
- package/dist/lib/testing/scenarios/capabilities.mjs +9 -42
- package/dist/lib/testing/storyboard/creative-build-probe.d.mts +34 -0
- package/dist/lib/testing/storyboard/creative-build-probe.d.ts +34 -0
- package/dist/lib/testing/storyboard/creative-build-probe.js +395 -0
- package/dist/lib/testing/storyboard/creative-build-probe.mjs +373 -0
- package/dist/lib/testing/storyboard/index.d.mts +2 -0
- package/dist/lib/testing/storyboard/index.d.ts +2 -0
- package/dist/lib/testing/storyboard/index.js +5 -0
- package/dist/lib/testing/storyboard/index.mjs +3 -0
- package/dist/lib/testing/storyboard/loader.js +12 -0
- package/dist/lib/testing/storyboard/loader.mjs +12 -0
- package/dist/lib/testing/storyboard/property-list-reference.d.mts +15 -0
- package/dist/lib/testing/storyboard/property-list-reference.d.ts +15 -0
- package/dist/lib/testing/storyboard/property-list-reference.js +514 -0
- package/dist/lib/testing/storyboard/property-list-reference.mjs +487 -0
- package/dist/lib/testing/storyboard/runner.js +318 -58
- package/dist/lib/testing/storyboard/runner.mjs +322 -58
- package/dist/lib/testing/storyboard/types.d.mts +38 -16
- package/dist/lib/testing/storyboard/types.d.ts +38 -16
- package/dist/lib/testing/storyboard/types.js +1 -0
- package/dist/lib/testing/storyboard/types.mjs +1 -0
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/validations.js +64 -0
- package/dist/lib/testing/storyboard/validations.mjs +67 -1
- package/dist/lib/testing/types.d.mts +15 -1
- package/dist/lib/testing/types.d.ts +15 -1
- package/dist/lib/types/schemas.generated.d.ts +65 -65
- package/dist/lib/types/wellknown-schemas.generated.d.mts +21 -21
- package/dist/lib/types/wellknown-schemas.generated.d.ts +21 -21
- package/dist/lib/utils/adcp-version-config.js +6 -0
- package/dist/lib/utils/adcp-version-config.mjs +6 -0
- package/dist/lib/utils/capabilities.d.mts +7 -9
- package/dist/lib/utils/capabilities.d.ts +7 -9
- package/dist/lib/utils/capabilities.js +14 -28
- package/dist/lib/utils/capabilities.mjs +14 -27
- package/dist/lib/utils/creative-adapter.d.mts +15 -113
- package/dist/lib/utils/creative-adapter.d.ts +15 -113
- package/dist/lib/utils/creative-adapter.js +7 -106
- package/dist/lib/utils/creative-adapter.mjs +7 -102
- package/dist/lib/utils/format-renders.d.mts +20 -80
- package/dist/lib/utils/format-renders.d.ts +20 -80
- package/dist/lib/utils/format-renders.js +7 -67
- package/dist/lib/utils/format-renders.mjs +7 -66
- package/dist/lib/utils/index.d.mts +1 -2
- package/dist/lib/utils/index.d.ts +1 -2
- package/dist/lib/utils/index.js +0 -7
- package/dist/lib/utils/index.mjs +0 -6
- package/dist/lib/utils/preview-normalizer.d.mts +31 -80
- package/dist/lib/utils/preview-normalizer.d.ts +31 -80
- package/dist/lib/utils/preview-normalizer.js +5 -50
- package/dist/lib/utils/preview-normalizer.mjs +5 -49
- package/dist/lib/utils/pricing-adapter.d.mts +2 -36
- package/dist/lib/utils/pricing-adapter.d.ts +2 -36
- package/dist/lib/utils/pricing-adapter.js +0 -105
- package/dist/lib/utils/pricing-adapter.mjs +0 -100
- package/dist/lib/utils/request-normalizer.d.mts +1 -2
- package/dist/lib/utils/request-normalizer.d.ts +1 -2
- package/dist/lib/v2/projection/creative-delivery.d.mts +2 -0
- package/dist/lib/v2/projection/creative-delivery.d.ts +2 -0
- package/dist/lib/v2/projection/creative-delivery.js +7 -0
- package/dist/lib/v2/projection/creative-delivery.mjs +6 -0
- package/dist/lib/v2/projection/legacy-metadata.d.mts +12 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts +12 -0
- package/dist/lib/v2/projection/legacy-metadata.js +41 -1
- package/dist/lib/v2/projection/legacy-metadata.mjs +37 -1
- package/dist/lib/v2/projection/legacy-normalization.d.mts +1 -1
- package/dist/lib/v2/projection/legacy-normalization.d.ts +1 -1
- package/dist/lib/v2/projection/v1-to-v2.js +13 -0
- package/dist/lib/v2/projection/v1-to-v2.mjs +14 -0
- package/dist/lib/validation/client-hooks.d.mts +1 -4
- package/dist/lib/validation/client-hooks.d.ts +1 -4
- package/dist/lib/validation/get-products-request.d.mts +1 -1
- package/dist/lib/validation/get-products-request.d.ts +1 -1
- package/dist/lib/validation/schema-loader.js +6 -0
- package/dist/lib/validation/schema-loader.mjs +6 -0
- package/dist/lib/validation/schema-validator.js +1 -26
- package/dist/lib/validation/schema-validator.mjs +1 -26
- package/dist/lib/version.d.mts +5 -5
- package/dist/lib/version.d.ts +5 -5
- package/dist/lib/version.js +3 -5
- package/dist/lib/version.mjs +3 -5
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/development/PROTOCOL_DIFFERENCES.md +1 -1
- package/docs/guides/CONFORMANCE.md +25 -0
- package/docs/guides/CREATIVE-BUILD-PROBE.md +156 -0
- package/docs/guides/CREATIVE-DELIVERY.md +45 -6
- package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +15 -18
- package/docs/guides/PROPERTY-LISTS.md +264 -0
- package/docs/guides/SIGNING-GUIDE.md +25 -0
- package/docs/guides/VALIDATE-YOUR-AGENT.md +5 -0
- package/docs/llms.txt +2 -2
- package/docs/migration-13-to-14.md +20 -16
- package/docs/migration-14.x-rc-worksheet.md +5 -5
- package/docs/migration-4.x-to-5.x.md +12 -7
- package/docs/migration-drop-adcp-2.md +25 -0
- package/package.json +3 -18
- package/skills/call-adcp-agent/SKILL.md +23 -25
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.d.mts +0 -3
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.d.ts +0 -3
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.js +0 -33
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs +0 -9
- package/dist/lib/adapters/legacy/v2-5/get_products.d.mts +0 -8
- package/dist/lib/adapters/legacy/v2-5/get_products.d.ts +0 -8
- package/dist/lib/adapters/legacy/v2-5/get_products.js +0 -33
- package/dist/lib/adapters/legacy/v2-5/get_products.mjs +0 -9
- package/dist/lib/adapters/legacy/v2-5/index.d.mts +0 -34
- package/dist/lib/adapters/legacy/v2-5/index.d.ts +0 -34
- package/dist/lib/adapters/legacy/v2-5/index.js +0 -50
- package/dist/lib/adapters/legacy/v2-5/index.mjs +0 -25
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.d.mts +0 -8
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.d.ts +0 -8
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.js +0 -33
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs +0 -9
- package/dist/lib/adapters/legacy/v2-5/preview_creative.d.mts +0 -3
- package/dist/lib/adapters/legacy/v2-5/preview_creative.d.ts +0 -3
- package/dist/lib/adapters/legacy/v2-5/preview_creative.js +0 -33
- package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs +0 -9
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.d.mts +0 -11
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.d.ts +0 -11
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.js +0 -32
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs +0 -8
- package/dist/lib/adapters/legacy/v2-5/types.d.mts +0 -39
- package/dist/lib/adapters/legacy/v2-5/types.d.ts +0 -39
- package/dist/lib/adapters/legacy/v2-5/types.js +0 -16
- package/dist/lib/adapters/legacy/v2-5/types.mjs +0 -0
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.d.mts +0 -3
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.d.ts +0 -3
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.js +0 -35
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs +0 -11
- package/dist/lib/schemas-data/v2.5/_provenance.json +0 -8
- package/dist/lib/schemas-data/v2.5/adagents.json +0 -494
- package/dist/lib/schemas-data/v2.5/core/activation-key.json +0 -50
- package/dist/lib/schemas-data/v2.5/core/assets/audio-asset.json +0 -32
- package/dist/lib/schemas-data/v2.5/core/assets/css-asset.json +0 -21
- package/dist/lib/schemas-data/v2.5/core/assets/daast-asset.json +0 -87
- package/dist/lib/schemas-data/v2.5/core/assets/html-asset.json +0 -21
- package/dist/lib/schemas-data/v2.5/core/assets/image-asset.json +0 -38
- package/dist/lib/schemas-data/v2.5/core/assets/javascript-asset.json +0 -21
- package/dist/lib/schemas-data/v2.5/core/assets/markdown-asset.json +0 -31
- package/dist/lib/schemas-data/v2.5/core/assets/text-asset.json +0 -21
- package/dist/lib/schemas-data/v2.5/core/assets/url-asset.json +0 -26
- package/dist/lib/schemas-data/v2.5/core/assets/vast-asset.json +0 -87
- package/dist/lib/schemas-data/v2.5/core/assets/video-asset.json +0 -44
- package/dist/lib/schemas-data/v2.5/core/assets/webhook-asset.json +0 -71
- package/dist/lib/schemas-data/v2.5/core/async-response-data.json +0 -88
- package/dist/lib/schemas-data/v2.5/core/brand-manifest-ref.json +0 -33
- package/dist/lib/schemas-data/v2.5/core/brand-manifest.json +0 -409
- package/dist/lib/schemas-data/v2.5/core/context.json +0 -8
- package/dist/lib/schemas-data/v2.5/core/creative-asset.json +0 -125
- package/dist/lib/schemas-data/v2.5/core/creative-assignment.json +0 -31
- package/dist/lib/schemas-data/v2.5/core/creative-filters.json +0 -111
- package/dist/lib/schemas-data/v2.5/core/creative-manifest.json +0 -72
- package/dist/lib/schemas-data/v2.5/core/creative-policy.json +0 -27
- package/dist/lib/schemas-data/v2.5/core/delivery-metrics.json +0 -171
- package/dist/lib/schemas-data/v2.5/core/deployment.json +0 -93
- package/dist/lib/schemas-data/v2.5/core/destination.json +0 -53
- package/dist/lib/schemas-data/v2.5/core/error.json +0 -40
- package/dist/lib/schemas-data/v2.5/core/ext.json +0 -8
- package/dist/lib/schemas-data/v2.5/core/format-id.json +0 -47
- package/dist/lib/schemas-data/v2.5/core/format.json +0 -324
- package/dist/lib/schemas-data/v2.5/core/frequency-cap.json +0 -18
- package/dist/lib/schemas-data/v2.5/core/mcp-webhook-payload.json +0 -152
- package/dist/lib/schemas-data/v2.5/core/measurement.json +0 -48
- package/dist/lib/schemas-data/v2.5/core/media-buy.json +0 -62
- package/dist/lib/schemas-data/v2.5/core/package.json +0 -72
- package/dist/lib/schemas-data/v2.5/core/performance-feedback.json +0 -90
- package/dist/lib/schemas-data/v2.5/core/placement.json +0 -34
- package/dist/lib/schemas-data/v2.5/core/pricing-option.json +0 -35
- package/dist/lib/schemas-data/v2.5/core/product-filters.json +0 -102
- package/dist/lib/schemas-data/v2.5/core/product.json +0 -153
- package/dist/lib/schemas-data/v2.5/core/promoted-offerings.json +0 -115
- package/dist/lib/schemas-data/v2.5/core/promoted-products.json +0 -67
- package/dist/lib/schemas-data/v2.5/core/property-id.json +0 -14
- package/dist/lib/schemas-data/v2.5/core/property-tag.json +0 -16
- package/dist/lib/schemas-data/v2.5/core/property.json +0 -62
- package/dist/lib/schemas-data/v2.5/core/protocol-envelope.json +0 -146
- package/dist/lib/schemas-data/v2.5/core/publisher-property-selector.json +0 -92
- package/dist/lib/schemas-data/v2.5/core/push-notification-config.json +0 -48
- package/dist/lib/schemas-data/v2.5/core/reporting-capabilities.json +0 -71
- package/dist/lib/schemas-data/v2.5/core/response.json +0 -24
- package/dist/lib/schemas-data/v2.5/core/signal-filters.json +0 -35
- package/dist/lib/schemas-data/v2.5/core/start-timing.json +0 -18
- package/dist/lib/schemas-data/v2.5/core/sub-asset.json +0 -79
- package/dist/lib/schemas-data/v2.5/core/targeting.json +0 -50
- package/dist/lib/schemas-data/v2.5/core/tasks-get-request.json +0 -43
- package/dist/lib/schemas-data/v2.5/core/tasks-get-response.json +0 -166
- package/dist/lib/schemas-data/v2.5/core/tasks-list-request.json +0 -192
- package/dist/lib/schemas-data/v2.5/core/tasks-list-response.json +0 -183
- package/dist/lib/schemas-data/v2.5/creative/asset-types/index.json +0 -101
- package/dist/lib/schemas-data/v2.5/creative/list-creative-formats-request.json +0 -73
- package/dist/lib/schemas-data/v2.5/creative/list-creative-formats-response.json +0 -61
- package/dist/lib/schemas-data/v2.5/creative/preview-creative-request.json +0 -164
- package/dist/lib/schemas-data/v2.5/creative/preview-creative-response.json +0 -245
- package/dist/lib/schemas-data/v2.5/creative/preview-render.json +0 -225
- package/dist/lib/schemas-data/v2.5/enums/adcp-domain.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/asset-content-type.json +0 -22
- package/dist/lib/schemas-data/v2.5/enums/auth-scheme.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/available-metric.json +0 -18
- package/dist/lib/schemas-data/v2.5/enums/channels.json +0 -18
- package/dist/lib/schemas-data/v2.5/enums/co-branding-requirement.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/creative-action.json +0 -14
- package/dist/lib/schemas-data/v2.5/enums/creative-agent-capability.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/creative-sort-field.json +0 -15
- package/dist/lib/schemas-data/v2.5/enums/creative-status.json +0 -19
- package/dist/lib/schemas-data/v2.5/enums/daast-tracking-event.json +0 -20
- package/dist/lib/schemas-data/v2.5/enums/daast-version.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/delivery-type.json +0 -15
- package/dist/lib/schemas-data/v2.5/enums/dimension-unit.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/feed-format.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/feedback-source.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/format-category.json +0 -16
- package/dist/lib/schemas-data/v2.5/enums/format-id-parameter.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/frequency-cap-scope.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/history-entry-type.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/http-method.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/identifier-types.json +0 -34
- package/dist/lib/schemas-data/v2.5/enums/javascript-module-type.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/landing-page-requirement.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/markdown-flavor.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/media-buy-status.json +0 -19
- package/dist/lib/schemas-data/v2.5/enums/metric-type.json +0 -17
- package/dist/lib/schemas-data/v2.5/enums/notification-type.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/pacing.json +0 -17
- package/dist/lib/schemas-data/v2.5/enums/preview-output-format.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/pricing-model.json +0 -25
- package/dist/lib/schemas-data/v2.5/enums/property-type.json +0 -16
- package/dist/lib/schemas-data/v2.5/enums/publisher-identifier-types.json +0 -19
- package/dist/lib/schemas-data/v2.5/enums/reporting-frequency.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/signal-catalog-type.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/sort-direction.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/standard-format-ids.json +0 -103
- package/dist/lib/schemas-data/v2.5/enums/task-status.json +0 -29
- package/dist/lib/schemas-data/v2.5/enums/task-type.json +0 -27
- package/dist/lib/schemas-data/v2.5/enums/update-frequency.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/url-asset-type.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/validation-mode.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/vast-tracking-event.json +0 -25
- package/dist/lib/schemas-data/v2.5/enums/vast-version.json +0 -14
- package/dist/lib/schemas-data/v2.5/enums/webhook-response-type.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/webhook-security-method.json +0 -12
- package/dist/lib/schemas-data/v2.5/index.json +0 -604
- package/dist/lib/schemas-data/v2.5/media-buy/build-creative-request.json +0 -31
- package/dist/lib/schemas-data/v2.5/media-buy/build-creative-response.json +0 -65
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-async-response-input-required.json +0 -31
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-async-response-submitted.json +0 -16
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-async-response-working.json +0 -36
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-request.json +0 -126
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-response.json +0 -97
- package/dist/lib/schemas-data/v2.5/media-buy/get-media-buy-delivery-request.json +0 -54
- package/dist/lib/schemas-data/v2.5/media-buy/get-media-buy-delivery-response.json +0 -285
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-async-response-input-required.json +0 -38
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-async-response-submitted.json +0 -21
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-async-response-working.json +0 -34
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-request.json +0 -28
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-response.json +0 -33
- package/dist/lib/schemas-data/v2.5/media-buy/list-authorized-properties-request.json +0 -26
- package/dist/lib/schemas-data/v2.5/media-buy/list-authorized-properties-response.json +0 -70
- package/dist/lib/schemas-data/v2.5/media-buy/list-creative-formats-request.json +0 -58
- package/dist/lib/schemas-data/v2.5/media-buy/list-creative-formats-response.json +0 -61
- package/dist/lib/schemas-data/v2.5/media-buy/list-creatives-request.json +0 -137
- package/dist/lib/schemas-data/v2.5/media-buy/list-creatives-response.json +0 -437
- package/dist/lib/schemas-data/v2.5/media-buy/package-request.json +0 -80
- package/dist/lib/schemas-data/v2.5/media-buy/provide-performance-feedback-request.json +0 -88
- package/dist/lib/schemas-data/v2.5/media-buy/provide-performance-feedback-response.json +0 -66
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-async-response-input-required.json +0 -25
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-async-response-submitted.json +0 -16
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-async-response-working.json +0 -46
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-request.json +0 -178
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-response.json +0 -149
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-async-response-input-required.json +0 -24
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-async-response-submitted.json +0 -16
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-async-response-working.json +0 -36
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-request.json +0 -129
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-response.json +0 -99
- package/dist/lib/schemas-data/v2.5/pricing-options/cpc-option.json +0 -52
- package/dist/lib/schemas-data/v2.5/pricing-options/cpcv-option.json +0 -52
- package/dist/lib/schemas-data/v2.5/pricing-options/cpm-auction-option.json +0 -81
- package/dist/lib/schemas-data/v2.5/pricing-options/cpm-fixed-option.json +0 -52
- package/dist/lib/schemas-data/v2.5/pricing-options/cpp-option.json +0 -73
- package/dist/lib/schemas-data/v2.5/pricing-options/cpv-option.json +0 -88
- package/dist/lib/schemas-data/v2.5/pricing-options/flat-rate-option.json +0 -93
- package/dist/lib/schemas-data/v2.5/pricing-options/vcpm-auction-option.json +0 -81
- package/dist/lib/schemas-data/v2.5/pricing-options/vcpm-fixed-option.json +0 -52
- package/dist/lib/schemas-data/v2.5/protocols/adcp-extension.json +0 -33
- package/dist/lib/schemas-data/v2.5/signals/activate-signal-request.json +0 -32
- package/dist/lib/schemas-data/v2.5/signals/activate-signal-response.json +0 -68
- package/dist/lib/schemas-data/v2.5/signals/get-signals-request.json +0 -59
- package/dist/lib/schemas-data/v2.5/signals/get-signals-response.json +0 -100
- package/dist/lib/types/v2-5/index.d.mts +0 -1
- package/dist/lib/types/v2-5/index.d.ts +0 -1
- package/dist/lib/types/v2-5/index.js +0 -22
- package/dist/lib/types/v2-5/index.mjs +0 -1
- package/dist/lib/types/v2-5/tools.generated.d.mts +0 -3568
- package/dist/lib/types/v2-5/tools.generated.d.ts +0 -3568
- package/dist/lib/types/v2-5/tools.generated.js +0 -16
- package/dist/lib/types/v2-5/tools.generated.mjs +0 -0
- package/dist/lib/utils/sync-creatives-adapter.d.mts +0 -33
- package/dist/lib/utils/sync-creatives-adapter.d.ts +0 -33
- package/dist/lib/utils/sync-creatives-adapter.js +0 -83
- package/dist/lib/utils/sync-creatives-adapter.mjs +0 -59
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
|
+
import { StreamableHTTPClientTransport, StreamableHTTPError } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
4
|
+
import { createAgentTransportFetch } from "../../net/index.mjs";
|
|
5
|
+
import { terminateSessionBestEffort } from "../../protocols/session-termination.mjs";
|
|
6
|
+
import { getSchemaValidatorByRef } from "../../validation/schema-loader.mjs";
|
|
7
|
+
import { SECRET_KEY_PATTERN } from "../../utils/redact-secrets.mjs";
|
|
8
|
+
import { globalAsyncLocalStorage } from "../../utils/global-async-local-storage.mjs";
|
|
9
|
+
import { ADCP_VERSION } from "../../version.mjs";
|
|
10
|
+
import { resolvePath } from "./path.mjs";
|
|
11
|
+
const credentials = globalAsyncLocalStorage("property-list-reference-credentials");
|
|
12
|
+
const REPORT_SECRET_PATTERN = new RegExp(`${SECRET_KEY_PATTERN.source}|^auth[_-]token$`, "i");
|
|
13
|
+
function rememberPropertyListCredentials(data, paths = []) {
|
|
14
|
+
const values = credentials.getStore();
|
|
15
|
+
if (!values) return;
|
|
16
|
+
const object = record(data);
|
|
17
|
+
for (const path of ["auth_token", ...paths]) {
|
|
18
|
+
const value = resolvePath(object, path);
|
|
19
|
+
if (typeof value === "string" && value.length > 0) values.add(value);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function redactPropertyListCredentials(value) {
|
|
23
|
+
const secrets = [...credentials.getStore() ?? []].sort((a, b) => b.length - a.length);
|
|
24
|
+
if (!secrets.length) return value;
|
|
25
|
+
const spellings = [...new Set(secrets.flatMap((secret) => [secret, JSON.stringify(secret).slice(1, -1)]))].sort(
|
|
26
|
+
(a, b) => b.length - a.length
|
|
27
|
+
);
|
|
28
|
+
const text = (s) => spellings.reduce((out, secret) => out.split(secret).join("[redacted]"), s);
|
|
29
|
+
const metadata = /* @__PURE__ */ new Set([
|
|
30
|
+
"check",
|
|
31
|
+
"step_id",
|
|
32
|
+
"phase_id",
|
|
33
|
+
"storyboard_id",
|
|
34
|
+
"task",
|
|
35
|
+
"operation",
|
|
36
|
+
"transport",
|
|
37
|
+
"skip_reason",
|
|
38
|
+
"reason",
|
|
39
|
+
"requirement"
|
|
40
|
+
]);
|
|
41
|
+
const walk = (entry, depth, raw = false, field = "") => {
|
|
42
|
+
if (depth > 64) return "[redacted: depth limit]";
|
|
43
|
+
if (typeof entry === "string") return !raw && metadata.has(field) ? entry : text(entry);
|
|
44
|
+
if (Array.isArray(entry)) return entry.map((item) => walk(item, depth + 1, raw));
|
|
45
|
+
if (entry && typeof entry === "object") {
|
|
46
|
+
const out = Object.fromEntries(
|
|
47
|
+
Object.entries(entry).map(([key, item]) => {
|
|
48
|
+
const rawChild = raw || ["payload", "body", "context", "headers", "actual", "expected", "adcp_error"].includes(key) || key === "response" && ("step_id" in record(entry) || !("transport" in record(item) && "payload" in record(item)));
|
|
49
|
+
return [
|
|
50
|
+
raw ? text(key) : key,
|
|
51
|
+
raw && REPORT_SECRET_PATTERN.test(key) && (typeof item === "string" || typeof item === "number") ? "[redacted]" : walk(item, depth + 1, rawChild, key)
|
|
52
|
+
];
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
for (const symbol of Object.getOwnPropertySymbols(entry))
|
|
56
|
+
Object.defineProperty(out, symbol, Object.getOwnPropertyDescriptor(entry, symbol));
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
return entry;
|
|
60
|
+
};
|
|
61
|
+
return walk(value, 0);
|
|
62
|
+
}
|
|
63
|
+
async function withPropertyListCredentialRedaction(run) {
|
|
64
|
+
return credentials.run(/* @__PURE__ */ new Set(), async () => {
|
|
65
|
+
try {
|
|
66
|
+
return redactPropertyListCredentials(await run());
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (!credentials.getStore().size) throw error;
|
|
69
|
+
if (!(error instanceof Error)) throw redactPropertyListCredentials(error);
|
|
70
|
+
const details = redactPropertyListCredentials({
|
|
71
|
+
...error,
|
|
72
|
+
message: error.message,
|
|
73
|
+
stack: error.stack,
|
|
74
|
+
cause: error.cause
|
|
75
|
+
});
|
|
76
|
+
const clean = new Error(details.message, { cause: details.cause });
|
|
77
|
+
Object.assign(clean, details);
|
|
78
|
+
clean.name = redactPropertyListCredentials(error.name);
|
|
79
|
+
throw clean;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function record(value) {
|
|
84
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
85
|
+
}
|
|
86
|
+
function toolPayload(value) {
|
|
87
|
+
const result = record(value);
|
|
88
|
+
if (result.structuredContent !== void 0) return record(result.structuredContent);
|
|
89
|
+
const content = Array.isArray(result.content) ? result.content : [];
|
|
90
|
+
const texts = content.filter((item) => record(item).type === "text");
|
|
91
|
+
if (texts.length !== 1 || typeof record(texts[0]).text !== "string") return {};
|
|
92
|
+
try {
|
|
93
|
+
return record(JSON.parse(record(texts[0]).text));
|
|
94
|
+
} catch {
|
|
95
|
+
return {};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const AUTH_DENIALS = /* @__PURE__ */ new Set([
|
|
99
|
+
"AUTH_REQUIRED",
|
|
100
|
+
"AUTH_MISSING",
|
|
101
|
+
"AUTH_INVALID",
|
|
102
|
+
"PERMISSION_DENIED",
|
|
103
|
+
"SCOPE_INSUFFICIENT",
|
|
104
|
+
"READ_ONLY_SCOPE"
|
|
105
|
+
]);
|
|
106
|
+
function containsListPayload(value, depth = 0) {
|
|
107
|
+
if (depth > 64) return true;
|
|
108
|
+
if (Array.isArray(value)) return value.some((item) => containsListPayload(item, depth + 1));
|
|
109
|
+
if (!value || typeof value !== "object") return false;
|
|
110
|
+
const object = record(value);
|
|
111
|
+
if ("list" in object || "identifiers" in object || object.status === "completed" || object.success === true)
|
|
112
|
+
return true;
|
|
113
|
+
return Object.values(object).some((item) => containsListPayload(item, depth + 1));
|
|
114
|
+
}
|
|
115
|
+
function isScopeDenial(raw, crossList, version) {
|
|
116
|
+
const payloads = [];
|
|
117
|
+
if (record(raw).structuredContent !== void 0) payloads.push(record(record(raw).structuredContent));
|
|
118
|
+
const content = Array.isArray(record(raw).content) ? record(raw).content : [];
|
|
119
|
+
for (const block of content) {
|
|
120
|
+
if (record(block).type !== "text" || typeof record(block).text !== "string") return false;
|
|
121
|
+
try {
|
|
122
|
+
payloads.push(record(JSON.parse(record(block).text)));
|
|
123
|
+
} catch {
|
|
124
|
+
if (record(raw).structuredContent === void 0) return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return payloads.length > 0 && payloads.every((payload) => isDenialPayload(payload, crossList, version));
|
|
128
|
+
}
|
|
129
|
+
function isDenialPayload(payload, crossList, version) {
|
|
130
|
+
if (containsListPayload(payload) || "result" in payload || "payload" in payload) return false;
|
|
131
|
+
if (payload.status !== void 0 && payload.status !== "failed" && payload.status !== "rejected") return false;
|
|
132
|
+
const envelope = getSchemaValidatorByRef("core/protocol-envelope.json", version);
|
|
133
|
+
if (!envelope || !envelope(payload)) return false;
|
|
134
|
+
if (payload.errors !== void 0 && !Array.isArray(payload.errors)) return false;
|
|
135
|
+
const errors = [
|
|
136
|
+
...Array.isArray(payload.errors) ? payload.errors : [],
|
|
137
|
+
...payload.adcp_error ? [payload.adcp_error] : []
|
|
138
|
+
];
|
|
139
|
+
const validate = getSchemaValidatorByRef("core/error.json", version);
|
|
140
|
+
return errors.length > 0 && !!validate && errors.every((error) => {
|
|
141
|
+
const code = record(error).code;
|
|
142
|
+
return validate(error) && record(error).severity !== "warning" && typeof code === "string" && (AUTH_DENIALS.has(code) || crossList && code === "REFERENCE_NOT_FOUND");
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function isHttpScopeDenial(capture, crossList, version) {
|
|
146
|
+
if (capture.status !== 401 && capture.status !== 403) return false;
|
|
147
|
+
if (capture.headers["content-type"]?.includes("text/event-stream")) return false;
|
|
148
|
+
if (!capture.body?.trim()) return true;
|
|
149
|
+
let body;
|
|
150
|
+
try {
|
|
151
|
+
const parsed = JSON.parse(capture.body);
|
|
152
|
+
if (Array.isArray(parsed) || containsListPayload(parsed)) return false;
|
|
153
|
+
body = record(parsed);
|
|
154
|
+
} catch {
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
if (containsListPayload(body) || "result" in body || "payload" in body) return false;
|
|
158
|
+
if ("errors" in body || "adcp_error" in body || "status" in body)
|
|
159
|
+
return isScopeDenial({ isError: true, structuredContent: body }, crossList, version);
|
|
160
|
+
if ("error" in body) return ["invalid_token", "insufficient_scope", "invalid_client"].includes(String(body.error));
|
|
161
|
+
if ("code" in body)
|
|
162
|
+
return isScopeDenial(
|
|
163
|
+
{ isError: true, structuredContent: { status: "failed", adcp_error: body } },
|
|
164
|
+
crossList,
|
|
165
|
+
version
|
|
166
|
+
);
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
async function verifyPropertyListReference(validation, creation, options) {
|
|
170
|
+
if (!credentials.getStore())
|
|
171
|
+
return withPropertyListCredentialRedaction(() => verifyPropertyListReference(validation, creation, options));
|
|
172
|
+
const observations = [];
|
|
173
|
+
let pointer = null;
|
|
174
|
+
let schemaRef;
|
|
175
|
+
let expectedResult = "complete token-only resolution and two authorization denials";
|
|
176
|
+
let actualResult = null;
|
|
177
|
+
const version = options.version ?? ADCP_VERSION;
|
|
178
|
+
const fail = (message) => {
|
|
179
|
+
throw new Error(message);
|
|
180
|
+
};
|
|
181
|
+
const requireSchema = (ref, value) => {
|
|
182
|
+
schemaRef = ref;
|
|
183
|
+
const validate = getSchemaValidatorByRef(ref, version);
|
|
184
|
+
if (!validate) fail(`Required probe schema is unavailable: ${ref}`);
|
|
185
|
+
if (!validate(value)) {
|
|
186
|
+
expectedResult = { schema_ref: ref };
|
|
187
|
+
actualResult = { issues: validate.errors };
|
|
188
|
+
pointer = validate.errors?.[0]?.instancePath ?? null;
|
|
189
|
+
fail(`Probe payload fails ${ref}: ${validate.errors?.[0]?.message ?? "schema violation"}`);
|
|
190
|
+
}
|
|
191
|
+
schemaRef = void 0;
|
|
192
|
+
pointer = null;
|
|
193
|
+
};
|
|
194
|
+
let client;
|
|
195
|
+
let transport;
|
|
196
|
+
let terminate;
|
|
197
|
+
const signal = options.signal ? AbortSignal.any([options.signal, AbortSignal.timeout(3e4)]) : AbortSignal.timeout(3e4);
|
|
198
|
+
try {
|
|
199
|
+
for (const secret of options.redactValues ?? []) if (secret) credentials.getStore().add(secret);
|
|
200
|
+
rememberPropertyListCredentials(creation, validation.auth_token_path ? [validation.auth_token_path] : []);
|
|
201
|
+
const listId = resolvePath(creation, validation.list_id_path ?? "list.list_id");
|
|
202
|
+
const token = resolvePath(creation, validation.auth_token_path ?? "auth_token");
|
|
203
|
+
if (typeof listId !== "string" || !listId.trim())
|
|
204
|
+
fail(`Issued list ID is missing at ${validation.list_id_path ?? "list.list_id"}.`);
|
|
205
|
+
if (typeof token !== "string" || !token.trim())
|
|
206
|
+
fail(`Issued reference credential is missing at ${validation.auth_token_path ?? "auth_token"}.`);
|
|
207
|
+
const deniedId = validation.denied_list_id;
|
|
208
|
+
if (typeof deniedId !== "string" || !deniedId.trim() || deniedId === listId || deniedId.includes("$context.") || deniedId.includes("{{"))
|
|
209
|
+
fail("An existing, distinct control list ID is required.");
|
|
210
|
+
const pageSize = validation.page_size;
|
|
211
|
+
const maxPages = validation.max_pages;
|
|
212
|
+
if (!Number.isInteger(pageSize) || pageSize < 1 || pageSize > 1e4)
|
|
213
|
+
fail("page_size must be an integer in [1, 10000].");
|
|
214
|
+
if (!Number.isInteger(maxPages) || maxPages < 1 || maxPages > 100)
|
|
215
|
+
fail("max_pages must be an integer in [1, 100].");
|
|
216
|
+
if (!Array.isArray(validation.expected_identifiers)) fail("expected_identifiers is required.");
|
|
217
|
+
const expected = validation.expected_identifiers;
|
|
218
|
+
for (const identifier of expected) requireSchema("core/identifier.json", identifier);
|
|
219
|
+
const key = (identifier) => JSON.stringify([record(identifier).type, record(identifier).value]);
|
|
220
|
+
const expectedSet = new Set(expected.map(key));
|
|
221
|
+
if (expectedSet.size !== expected.length) fail("expected_identifiers contains duplicates.");
|
|
222
|
+
const endpoint = new URL(
|
|
223
|
+
validation.agent_url === "$agent_url" || !validation.agent_url ? options.agentUrl : validation.agent_url
|
|
224
|
+
);
|
|
225
|
+
if (endpoint.href !== new URL(options.agentUrl).href)
|
|
226
|
+
fail("The probe endpoint must match the agent that issued the reference.");
|
|
227
|
+
if (endpoint.username || endpoint.password || endpoint.search || endpoint.hash)
|
|
228
|
+
fail("The isolated endpoint must not contain URL credentials, query parameters, or a fragment.");
|
|
229
|
+
if (endpoint.protocol !== "https:" && !(options.allowHttp && endpoint.protocol === "http:"))
|
|
230
|
+
fail("The isolated endpoint requires HTTPS (or allow_http for local tests).");
|
|
231
|
+
const network = createAgentTransportFetch(endpoint.href, {
|
|
232
|
+
allowPrivateIp: options.allowHttp === true,
|
|
233
|
+
allowPrivateInitialOrigin: false
|
|
234
|
+
});
|
|
235
|
+
let bytes = 0;
|
|
236
|
+
let exchanges = 0;
|
|
237
|
+
let issuedSessionId;
|
|
238
|
+
const wireCaptures = [];
|
|
239
|
+
const isolatedFetch = async (input, init) => {
|
|
240
|
+
if (typeof init?.body === "string") {
|
|
241
|
+
const outgoing = record(JSON.parse(init.body));
|
|
242
|
+
if (outgoing.method === "initialize") Object.assign(request, record(outgoing.params));
|
|
243
|
+
}
|
|
244
|
+
if (++exchanges > maxPages + 16) fail("Probe exceeded its transport request budget.");
|
|
245
|
+
const url = new URL(input instanceof Request ? input.url : input.toString());
|
|
246
|
+
if (url.href !== endpoint.href) fail("MCP attempted to leave the managing endpoint.");
|
|
247
|
+
const response = await network(input, {
|
|
248
|
+
...init,
|
|
249
|
+
signal: init?.signal ? AbortSignal.any([init.signal, signal]) : signal,
|
|
250
|
+
redirect: "error",
|
|
251
|
+
credentials: "omit"
|
|
252
|
+
});
|
|
253
|
+
issuedSessionId = response.headers.get("mcp-session-id") ?? issuedSessionId;
|
|
254
|
+
const responseHeaders = {};
|
|
255
|
+
response.headers.forEach((value, key2) => {
|
|
256
|
+
responseHeaders[key2] = value;
|
|
257
|
+
});
|
|
258
|
+
const capture = {
|
|
259
|
+
url: url.href,
|
|
260
|
+
method: init?.method ?? "GET",
|
|
261
|
+
status: response.status,
|
|
262
|
+
headers: responseHeaders
|
|
263
|
+
};
|
|
264
|
+
wireCaptures.push(capture);
|
|
265
|
+
if (!response.body) return response;
|
|
266
|
+
let responseBytes = 0;
|
|
267
|
+
const bounded = new Response(
|
|
268
|
+
response.body.pipeThrough(
|
|
269
|
+
new TransformStream({
|
|
270
|
+
transform(chunk, controller) {
|
|
271
|
+
bytes += chunk.byteLength;
|
|
272
|
+
responseBytes += chunk.byteLength;
|
|
273
|
+
if (bytes > 4 * 1024 * 1024 || responseBytes > 1024 * 1024)
|
|
274
|
+
throw new Error("Probe response byte budget exceeded.");
|
|
275
|
+
controller.enqueue(chunk);
|
|
276
|
+
}
|
|
277
|
+
})
|
|
278
|
+
),
|
|
279
|
+
{ status: response.status, statusText: response.statusText, headers: response.headers }
|
|
280
|
+
);
|
|
281
|
+
if (!response.headers.get("content-type")?.includes("text/event-stream"))
|
|
282
|
+
capture.body = await bounded.clone().text();
|
|
283
|
+
return bounded;
|
|
284
|
+
};
|
|
285
|
+
client = new Client({ name: "adcp-property-list-reference-probe", version: "1.0.0" }, { capabilities: {} });
|
|
286
|
+
transport = new StreamableHTTPClientTransport(endpoint, {
|
|
287
|
+
requestInit: { headers: { Authorization: `Bearer ${token}` }, credentials: "omit", redirect: "error", signal },
|
|
288
|
+
fetch: isolatedFetch,
|
|
289
|
+
reconnectionOptions: {
|
|
290
|
+
maxRetries: 0,
|
|
291
|
+
maxReconnectionDelay: 1e3,
|
|
292
|
+
initialReconnectionDelay: 1e3,
|
|
293
|
+
reconnectionDelayGrowFactor: 1
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
terminate = async () => {
|
|
297
|
+
if (!issuedSessionId) return;
|
|
298
|
+
const terminator = new StreamableHTTPClientTransport(endpoint, {
|
|
299
|
+
sessionId: issuedSessionId,
|
|
300
|
+
requestInit: {
|
|
301
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
302
|
+
credentials: "omit",
|
|
303
|
+
redirect: "error",
|
|
304
|
+
signal: AbortSignal.timeout(1e3)
|
|
305
|
+
},
|
|
306
|
+
fetch: (input, init) => network(input, { ...init, signal: AbortSignal.timeout(1e3), redirect: "error", credentials: "omit" })
|
|
307
|
+
});
|
|
308
|
+
try {
|
|
309
|
+
await terminateSessionBestEffort(terminator);
|
|
310
|
+
} finally {
|
|
311
|
+
await terminator.close().catch(() => {
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
const rpcOptions = { signal, timeout: 3e4 };
|
|
316
|
+
let operation = "initialize";
|
|
317
|
+
let request = {};
|
|
318
|
+
const observe = async (invoke) => {
|
|
319
|
+
const requestRecord = {
|
|
320
|
+
transport: "mcp",
|
|
321
|
+
operation,
|
|
322
|
+
url: endpoint.href,
|
|
323
|
+
headers: { authorization: "[redacted]" },
|
|
324
|
+
payload: request
|
|
325
|
+
};
|
|
326
|
+
const started = Date.now();
|
|
327
|
+
const captureStart = wireCaptures.length;
|
|
328
|
+
try {
|
|
329
|
+
const result = await invoke();
|
|
330
|
+
observations.push({
|
|
331
|
+
request: requestRecord,
|
|
332
|
+
response: { transport: "mcp", payload: result, duration_ms: Date.now() - started },
|
|
333
|
+
wire_responses: wireCaptures.slice(captureStart)
|
|
334
|
+
});
|
|
335
|
+
return result;
|
|
336
|
+
} catch (error) {
|
|
337
|
+
observations.push({
|
|
338
|
+
request: requestRecord,
|
|
339
|
+
response: {
|
|
340
|
+
transport: "mcp",
|
|
341
|
+
payload: null,
|
|
342
|
+
...error instanceof StreamableHTTPError && { status: error.code },
|
|
343
|
+
duration_ms: Date.now() - started
|
|
344
|
+
},
|
|
345
|
+
wire_responses: wireCaptures.slice(captureStart),
|
|
346
|
+
error: error instanceof Error ? error.message : "Transport failure"
|
|
347
|
+
});
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
await observe(async () => {
|
|
352
|
+
await client.connect(transport, rpcOptions);
|
|
353
|
+
return { serverInfo: client.getServerVersion(), capabilities: client.getServerCapabilities() };
|
|
354
|
+
});
|
|
355
|
+
const call = async (name, args) => {
|
|
356
|
+
operation = name;
|
|
357
|
+
request = args;
|
|
358
|
+
requireSchema(`property/${name.replaceAll("_", "-")}-request.json`, args);
|
|
359
|
+
return observe(() => client.callTool({ name, arguments: args }, void 0, rpcOptions));
|
|
360
|
+
};
|
|
361
|
+
const identifiers = /* @__PURE__ */ new Set();
|
|
362
|
+
const cursors = /* @__PURE__ */ new Set();
|
|
363
|
+
let cursor;
|
|
364
|
+
let pages = 0;
|
|
365
|
+
for (; ; ) {
|
|
366
|
+
if (++pages > maxPages) fail("Pagination exceeded max_pages.");
|
|
367
|
+
const raw = await call("get_property_list", {
|
|
368
|
+
list_id: listId,
|
|
369
|
+
resolve: true,
|
|
370
|
+
pagination: { max_results: pageSize, ...cursor && { cursor } }
|
|
371
|
+
});
|
|
372
|
+
if (record(raw).isError === true) {
|
|
373
|
+
actualResult = toolPayload(raw);
|
|
374
|
+
fail(`Page ${pages}: get_property_list was rejected; the issued Bearer must work without an account argument.`);
|
|
375
|
+
}
|
|
376
|
+
const payload = toolPayload(raw);
|
|
377
|
+
requireSchema("property/get-property-list-response.json", payload);
|
|
378
|
+
if (payload.status !== void 0 && payload.status !== "completed" || payload.adcp_error)
|
|
379
|
+
fail(`Page ${pages}: list resolution did not complete successfully.`);
|
|
380
|
+
pointer = "/list/list_id";
|
|
381
|
+
if (record(payload.list).list_id !== listId) fail(`Page ${pages}: returned another list.`);
|
|
382
|
+
pointer = "/identifiers";
|
|
383
|
+
if (!Array.isArray(payload.identifiers) || payload.identifiers.length > pageSize)
|
|
384
|
+
fail(`Page ${pages}: missing identifiers or page exceeds page_size.`);
|
|
385
|
+
for (const identifier of payload.identifiers) {
|
|
386
|
+
const id = key(identifier);
|
|
387
|
+
if (identifiers.has(id)) fail(`Page ${pages}: duplicate identifier.`);
|
|
388
|
+
identifiers.add(id);
|
|
389
|
+
}
|
|
390
|
+
pointer = "/pagination";
|
|
391
|
+
const pagination = record(payload.pagination);
|
|
392
|
+
if (payload.pagination === void 0 && pages === 1 && expected.length <= pageSize) break;
|
|
393
|
+
if (typeof pagination.has_more !== "boolean") fail(`Page ${pages}: pagination.has_more is required.`);
|
|
394
|
+
if (pagination.has_more === false) {
|
|
395
|
+
if (pagination.cursor !== void 0) fail(`Page ${pages}: terminal page carries a continuation cursor.`);
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
if (typeof pagination.cursor !== "string" || !pagination.cursor || cursors.has(pagination.cursor))
|
|
399
|
+
fail(`Page ${pages}: missing or repeated continuation cursor.`);
|
|
400
|
+
cursors.add(pagination.cursor);
|
|
401
|
+
cursor = pagination.cursor;
|
|
402
|
+
}
|
|
403
|
+
pointer = "/identifiers";
|
|
404
|
+
expectedResult = expected;
|
|
405
|
+
actualResult = {
|
|
406
|
+
missing: expected.filter((identifier) => !identifiers.has(key(identifier))),
|
|
407
|
+
unexpected: [...identifiers].filter((id) => !expectedSet.has(id)).map((id) => JSON.parse(id))
|
|
408
|
+
};
|
|
409
|
+
if (expected.length > pageSize && pages < 2) fail("The fixture requires multiple pages.");
|
|
410
|
+
if (identifiers.size !== expectedSet.size || [...expectedSet].some((id) => !identifiers.has(id)))
|
|
411
|
+
fail("The complete snapshot does not equal expected_identifiers.");
|
|
412
|
+
const denial = async (name, args, crossList) => {
|
|
413
|
+
pointer = null;
|
|
414
|
+
expectedResult = { authorization: "denied", operation: name };
|
|
415
|
+
let denied = false;
|
|
416
|
+
const denialStart = wireCaptures.length;
|
|
417
|
+
try {
|
|
418
|
+
const raw = await call(name, args);
|
|
419
|
+
actualResult = toolPayload(raw);
|
|
420
|
+
const serialized = JSON.stringify(raw);
|
|
421
|
+
denied = !expected.some((identifier) => serialized.includes(identifier.value)) && isScopeDenial(raw, crossList, version);
|
|
422
|
+
} catch (error) {
|
|
423
|
+
actualResult = {
|
|
424
|
+
error: error instanceof Error ? error.message : "Transport failure",
|
|
425
|
+
...error instanceof StreamableHTTPError && { status: error.code }
|
|
426
|
+
};
|
|
427
|
+
denied = error instanceof StreamableHTTPError && (error.code === 401 || error.code === 403);
|
|
428
|
+
const captures = wireCaptures.slice(denialStart).filter((capture) => capture.method.toUpperCase() === "POST");
|
|
429
|
+
denied = denied && captures.length > 0 && captures.every(
|
|
430
|
+
(capture) => isHttpScopeDenial(capture, crossList, version) && !expected.some((identifier) => capture.body?.includes(identifier.value))
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
if (!denied)
|
|
434
|
+
fail(
|
|
435
|
+
`${crossList ? "Cross-list read" : "Mutation"}: authorization denial was not established (${JSON.stringify(actualResult).slice(0, 512)}).`
|
|
436
|
+
);
|
|
437
|
+
observations.push({ probe: crossList ? "cross_list" : "mutation", authorization: "denied" });
|
|
438
|
+
};
|
|
439
|
+
await denial(
|
|
440
|
+
"get_property_list",
|
|
441
|
+
{ list_id: deniedId, resolve: true, pagination: { max_results: pageSize } },
|
|
442
|
+
true
|
|
443
|
+
);
|
|
444
|
+
await denial(
|
|
445
|
+
"update_property_list",
|
|
446
|
+
{ list_id: listId, name: `Credential isolation probe ${randomUUID()}`, idempotency_key: randomUUID() },
|
|
447
|
+
false
|
|
448
|
+
);
|
|
449
|
+
observations.push({
|
|
450
|
+
agent_url: endpoint.href,
|
|
451
|
+
list_id: listId,
|
|
452
|
+
page_count: pages,
|
|
453
|
+
identifier_count: identifiers.size
|
|
454
|
+
});
|
|
455
|
+
return redactPropertyListCredentials({
|
|
456
|
+
check: validation.check,
|
|
457
|
+
passed: true,
|
|
458
|
+
description: validation.description,
|
|
459
|
+
observations
|
|
460
|
+
});
|
|
461
|
+
} catch (error) {
|
|
462
|
+
const last = observations.slice().reverse().find((observation) => record(observation).request);
|
|
463
|
+
return redactPropertyListCredentials({
|
|
464
|
+
check: validation.check,
|
|
465
|
+
passed: false,
|
|
466
|
+
description: validation.description,
|
|
467
|
+
error: error instanceof Error ? error.message : "Reference probe failed.",
|
|
468
|
+
json_pointer: pointer,
|
|
469
|
+
schema_id: null,
|
|
470
|
+
schema_url: null,
|
|
471
|
+
expected: schemaRef ? { schema_ref: schemaRef } : expectedResult,
|
|
472
|
+
actual: actualResult ?? last?.response.payload ?? null,
|
|
473
|
+
...last && { request: last.request, response: last.response },
|
|
474
|
+
observations
|
|
475
|
+
});
|
|
476
|
+
} finally {
|
|
477
|
+
if (client) await client.close().catch(() => {
|
|
478
|
+
});
|
|
479
|
+
if (terminate) await terminate();
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
export {
|
|
483
|
+
redactPropertyListCredentials,
|
|
484
|
+
rememberPropertyListCredentials,
|
|
485
|
+
verifyPropertyListReference,
|
|
486
|
+
withPropertyListCredentialRedaction
|
|
487
|
+
};
|