@adcp/sdk 16.0.0-beta.8 → 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 +3 -0
- package/bin/adcp.js +10 -13
- 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 +19 -112
- package/dist/lib/core/SingleAgentClient.d.ts +19 -112
- package/dist/lib/core/SingleAgentClient.js +270 -252
- package/dist/lib/core/SingleAgentClient.mjs +275 -253
- 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/index.d.mts +4 -4
- package/dist/lib/index.d.ts +4 -4
- package/dist/lib/index.js +0 -14
- package/dist/lib/index.mjs +0 -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/legacy-purchase-continuation.d.mts +2 -2
- package/dist/lib/media-buy/legacy-purchase-continuation.d.ts +2 -2
- package/dist/lib/protocols/index.js +14 -22
- package/dist/lib/protocols/index.mjs +5 -13
- package/dist/lib/registry/types.d.mts +3 -2
- package/dist/lib/registry/types.d.ts +3 -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/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/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
|
+
};
|