@adcp/sdk 6.9.0 → 6.11.0
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/bin/adcp.js +285 -5
- package/compliance/cache/3.0.6.previous/domains/brand/index.yaml +163 -0
- package/compliance/cache/3.0.6.previous/domains/creative/index.yaml +412 -0
- package/compliance/cache/3.0.6.previous/domains/governance/index.yaml +683 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/creative-reception.yaml +247 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/index.yaml +769 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/create_media_buy_async.yaml +232 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +414 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/delivery_reporting.yaml +205 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/governance_approved.yaml +211 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/governance_conditions.yaml +196 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/governance_denied.yaml +192 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/governance_denied_recovery.yaml +244 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/invalid_transitions.yaml +284 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/inventory_list_no_match.yaml +143 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/inventory_list_targeting.yaml +271 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/measurement_terms_rejected.yaml +195 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/pending_creatives_to_start.yaml +250 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/proposal_finalize.yaml +243 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.0.6.previous/domains/signals/index.yaml +266 -0
- package/compliance/cache/3.0.6.previous/domains/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.0.6.previous/index.json +324 -0
- package/compliance/cache/3.0.6.previous/protocols/brand/index.yaml +163 -0
- package/compliance/cache/3.0.6.previous/protocols/creative/index.yaml +412 -0
- package/compliance/cache/3.0.6.previous/protocols/governance/index.yaml +683 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/creative-reception.yaml +247 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/index.yaml +769 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/create_media_buy_async.yaml +232 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +414 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/delivery_reporting.yaml +205 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/governance_approved.yaml +211 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/governance_conditions.yaml +196 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/governance_denied.yaml +192 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/governance_denied_recovery.yaml +244 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/invalid_transitions.yaml +284 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/inventory_list_no_match.yaml +143 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/inventory_list_targeting.yaml +271 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +195 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +250 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/proposal_finalize.yaml +243 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.0.6.previous/protocols/signals/index.yaml +266 -0
- package/compliance/cache/3.0.6.previous/protocols/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.0.6.previous/specialisms/audience-sync/index.yaml +280 -0
- package/compliance/cache/3.0.6.previous/specialisms/brand-rights/index.yaml +350 -0
- package/compliance/cache/3.0.6.previous/specialisms/brand-rights/scenarios/governance_denied.yaml +204 -0
- package/compliance/cache/3.0.6.previous/specialisms/collection-lists/index.yaml +359 -0
- package/compliance/cache/3.0.6.previous/specialisms/content-standards/index.yaml +572 -0
- package/compliance/cache/3.0.6.previous/specialisms/creative-ad-server/index.yaml +383 -0
- package/compliance/cache/3.0.6.previous/specialisms/creative-generative/generative-seller.yaml +758 -0
- package/compliance/cache/3.0.6.previous/specialisms/creative-generative/index.yaml +746 -0
- package/compliance/cache/3.0.6.previous/specialisms/creative-template/index.yaml +413 -0
- package/compliance/cache/3.0.6.previous/specialisms/governance-aware-seller/index.yaml +136 -0
- package/compliance/cache/3.0.6.previous/specialisms/governance-delivery-monitor/index.yaml +441 -0
- package/compliance/cache/3.0.6.previous/specialisms/governance-spend-authority/denied.yaml +221 -0
- package/compliance/cache/3.0.6.previous/specialisms/governance-spend-authority/index.yaml +330 -0
- package/compliance/cache/3.0.6.previous/specialisms/property-lists/index.yaml +482 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-broadcast-tv/index.yaml +689 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-catalog-driven/index.yaml +779 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-guaranteed/index.yaml +504 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-non-guaranteed/index.yaml +428 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-proposal-mode/index.yaml +520 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-social/index.yaml +584 -0
- package/compliance/cache/3.0.6.previous/specialisms/signal-marketplace/index.yaml +415 -0
- package/compliance/cache/3.0.6.previous/specialisms/signal-marketplace/scenarios/governance_denied.yaml +207 -0
- package/compliance/cache/3.0.6.previous/specialisms/signal-owned/index.yaml +316 -0
- package/compliance/cache/3.0.6.previous/test-kits/acme-outdoor.yaml +210 -0
- package/compliance/cache/3.0.6.previous/test-kits/bistro-oranje.yaml +126 -0
- package/compliance/cache/3.0.6.previous/test-kits/nova-motors.yaml +262 -0
- package/compliance/cache/3.0.6.previous/test-kits/osei-natural.yaml +126 -0
- package/compliance/cache/3.0.6.previous/test-kits/signed-requests-runner.yaml +155 -0
- package/compliance/cache/3.0.6.previous/test-kits/substitution-observer-runner.yaml +690 -0
- package/compliance/cache/3.0.6.previous/test-kits/summit-foods.yaml +125 -0
- package/compliance/cache/3.0.6.previous/test-kits/webhook-receiver-runner.yaml +265 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/001-minimal-plan.json +43 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/002-full-plan.json +217 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/003-bookkeeping-stripped.json +60 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/004a-human-review-omitted.json +43 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/004b-human-review-explicit-null.json +49 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/005a-policy-categories-order-1.json +53 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/005b-policy-categories-order-2.json +57 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/006a-ext-trace-v1.json +49 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/006b-ext-trace-v2.json +53 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/007-unicode-objectives.json +43 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/008-numeric-canonicalization.json +65 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/README.md +219 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/canonicalization.json +241 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/keys.json +60 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/001-no-signature-header.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/002-wrong-tag.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/003-expired-signature.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/004-window-too-long.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/005-alg-not-allowed.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/006-missing-covered-component.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/007-missing-content-digest.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/008-unknown-keyid.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +27 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/010-content-digest-mismatch.json +33 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/011-malformed-header.json +27 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/013-expires-le-created.json +27 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/014-missing-nonce-param.json +27 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/015-signature-invalid.json +28 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/016-replayed-nonce.json +35 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/017-key-revoked.json +38 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +28 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/019-signature-without-signature-input.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/020-rate-abuse.json +34 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/022-multi-valued-content-type.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +32 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/024-unquoted-string-param.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +43 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/026-non-ascii-host.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +25 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/001-basic-post.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/002-post-with-content-digest.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/003-es256-post.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/004-multiple-signature-labels.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/005-default-port-stripped.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/006-dot-segment-path.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/007-query-byte-preserved.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/008-percent-encoded-path.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/011-ipv6-authority.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/README.md +211 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/keys.json +61 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/001-wrong-tag.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/002-expired-signature.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/003-window-too-long.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/005-missing-authority-component.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/006-missing-content-digest.json +25 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/007-unknown-keyid.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/011-signature-without-input.json +25 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/013-expires-le-created.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/015-signature-invalid.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/016-replayed-nonce.json +37 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/017-key-revoked.json +32 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/018-rate-abuse.json +33 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/019-revocation-stale.json +32 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +41 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/001-basic-post.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/002-es256-post.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/004-default-port-stripped.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +25 -0
- package/compliance/cache/3.0.6.previous/universal/capability-discovery.yaml +125 -0
- package/compliance/cache/3.0.6.previous/universal/collection-lists-pagination-integrity.yaml +306 -0
- package/compliance/cache/3.0.6.previous/universal/content-standards-pagination-integrity.yaml +326 -0
- package/compliance/cache/3.0.6.previous/universal/deterministic-testing.yaml +1343 -0
- package/compliance/cache/3.0.6.previous/universal/error-compliance.yaml +474 -0
- package/compliance/cache/3.0.6.previous/universal/fictional-entities.yaml +307 -0
- package/compliance/cache/3.0.6.previous/universal/get-media-buys-pagination-integrity.yaml +160 -0
- package/compliance/cache/3.0.6.previous/universal/get-signals-pagination-integrity.yaml +211 -0
- package/compliance/cache/3.0.6.previous/universal/idempotency.yaml +593 -0
- package/compliance/cache/3.0.6.previous/universal/pagination-integrity-creative-formats.yaml +258 -0
- package/compliance/cache/3.0.6.previous/universal/pagination-integrity-list-accounts.yaml +262 -0
- package/compliance/cache/3.0.6.previous/universal/pagination-integrity.yaml +263 -0
- package/compliance/cache/3.0.6.previous/universal/property-lists-pagination-integrity.yaml +307 -0
- package/compliance/cache/3.0.6.previous/universal/runner-output-contract.yaml +358 -0
- package/compliance/cache/3.0.6.previous/universal/schema-validation.yaml +526 -0
- package/compliance/cache/3.0.6.previous/universal/security.yaml +431 -0
- package/compliance/cache/3.0.6.previous/universal/signed-requests.yaml +205 -0
- package/compliance/cache/3.0.6.previous/universal/storyboard-schema.yaml +1176 -0
- package/compliance/cache/3.0.6.previous/universal/v3-envelope-integrity.yaml +106 -0
- package/compliance/cache/3.0.6.previous/universal/webhook-emission.yaml +337 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/create-adcp-server.d.ts +33 -0
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +127 -1
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/credential-policy.d.ts +221 -0
- package/dist/lib/server/credential-policy.d.ts.map +1 -0
- package/dist/lib/server/credential-policy.js +260 -0
- package/dist/lib/server/credential-policy.js.map +1 -0
- package/dist/lib/server/decisioning/async-outcome.d.ts +17 -0
- package/dist/lib/server/decisioning/async-outcome.d.ts.map +1 -1
- package/dist/lib/server/decisioning/async-outcome.js +23 -18
- package/dist/lib/server/decisioning/async-outcome.js.map +1 -1
- package/dist/lib/server/decisioning/context.d.ts +8 -2
- package/dist/lib/server/decisioning/context.d.ts.map +1 -1
- package/dist/lib/server/decisioning/index.d.ts +1 -0
- package/dist/lib/server/decisioning/index.d.ts.map +1 -1
- package/dist/lib/server/decisioning/index.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.js +6 -4
- package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +5 -2
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.d.ts +5 -0
- package/dist/lib/server/decisioning/runtime/task-registry.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.js +4 -1
- package/dist/lib/server/decisioning/runtime/task-registry.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.js +10 -2
- package/dist/lib/server/decisioning/runtime/to-context.js.map +1 -1
- package/dist/lib/server/dynamic-registry.d.ts +219 -0
- package/dist/lib/server/dynamic-registry.d.ts.map +1 -0
- package/dist/lib/server/dynamic-registry.js +245 -0
- package/dist/lib/server/dynamic-registry.js.map +1 -0
- package/dist/lib/server/index.d.ts +8 -0
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +15 -4
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/operational-platform.d.ts +239 -0
- package/dist/lib/server/operational-platform.d.ts.map +1 -0
- package/dist/lib/server/operational-platform.js +94 -0
- package/dist/lib/server/operational-platform.js.map +1 -0
- package/dist/lib/server/test-controller.d.ts +2 -0
- package/dist/lib/server/test-controller.d.ts.map +1 -1
- package/dist/lib/server/test-controller.js +6 -11
- package/dist/lib/server/test-controller.js.map +1 -1
- package/dist/lib/server/wire-safe.d.ts +211 -0
- package/dist/lib/server/wire-safe.d.ts.map +1 -0
- package/dist/lib/server/wire-safe.js +231 -0
- package/dist/lib/server/wire-safe.js.map +1 -0
- package/dist/lib/server/wire-spec-fields.generated.d.ts +168 -0
- package/dist/lib/server/wire-spec-fields.generated.d.ts.map +1 -0
- package/dist/lib/server/wire-spec-fields.generated.js +172 -0
- package/dist/lib/server/wire-spec-fields.generated.js.map +1 -0
- package/dist/lib/testing/compliance/index.d.ts +2 -0
- package/dist/lib/testing/compliance/index.d.ts.map +1 -1
- package/dist/lib/testing/compliance/index.js +6 -1
- package/dist/lib/testing/compliance/index.js.map +1 -1
- package/dist/lib/testing/compliance/summary.d.ts +77 -0
- package/dist/lib/testing/compliance/summary.d.ts.map +1 -0
- package/dist/lib/testing/compliance/summary.js +176 -0
- package/dist/lib/testing/compliance/summary.js.map +1 -0
- package/dist/lib/testing/comply-controller.d.ts +2 -0
- package/dist/lib/testing/comply-controller.d.ts.map +1 -1
- package/dist/lib/testing/comply-controller.js.map +1 -1
- package/dist/lib/testing/storyboard/compliance.d.ts +26 -0
- package/dist/lib/testing/storyboard/compliance.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/compliance.js +51 -0
- package/dist/lib/testing/storyboard/compliance.js.map +1 -1
- package/dist/lib/testing/storyboard/index.d.ts +2 -2
- package/dist/lib/testing/storyboard/index.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/index.js +4 -2
- package/dist/lib/testing/storyboard/index.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +58 -5
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.d.ts.map +1 -1
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential discipline at the request boundary.
|
|
3
|
+
*
|
|
4
|
+
* Scans incoming buyer args for credential-shaped keys at any depth and
|
|
5
|
+
* rejects with `INVALID_REQUEST` when `credentialPolicy === 'authInfo-only'`.
|
|
6
|
+
* Closes the bug class observed in storefront fan-out paths where buyer-
|
|
7
|
+
* supplied keys like `<platform>_access_token` (top-level, in `context`,
|
|
8
|
+
* or in `ext`) flow through to upstream calls.
|
|
9
|
+
*
|
|
10
|
+
* Default mode is `'lax'` for back-compat. Opt into `'authInfo-only'` to
|
|
11
|
+
* enforce: credentials must arrive on `authInfo` (the framework-resolved
|
|
12
|
+
* bearer / signature / OAuth principal) and never on the args bag.
|
|
13
|
+
*
|
|
14
|
+
* Pattern set is extensible. Adopters whose platform vocabulary uses
|
|
15
|
+
* additional credential names extend via `credentialPolicy.patterns.extend`
|
|
16
|
+
* or replace the matcher entirely. Per-tool opt-out via
|
|
17
|
+
* `credentialPolicy.tools`.
|
|
18
|
+
*
|
|
19
|
+
* @see {@link AdcpServerConfig.credentialPolicy}
|
|
20
|
+
* @see docs/guides/CTX-METADATA-SAFETY.md
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Enforcement mode.
|
|
24
|
+
*
|
|
25
|
+
* - `'lax'` — no scan; current behavior.
|
|
26
|
+
* - `'authInfo-only'` — scan args for credential-shaped keys; reject any
|
|
27
|
+
* match with `INVALID_REQUEST` listing the offending paths (not values).
|
|
28
|
+
* Adopters who legitimately accept buyer-presented credentials opt out
|
|
29
|
+
* per-tool via {@link CredentialPolicyConfig.tools}.
|
|
30
|
+
*/
|
|
31
|
+
export type CredentialPolicyMode = 'lax' | 'authInfo-only';
|
|
32
|
+
/**
|
|
33
|
+
* Patterns that flag a key as credential-shaped. Values matching ANY
|
|
34
|
+
* regex (or returning `true` from the matcher) are treated as
|
|
35
|
+
* credential-bearing.
|
|
36
|
+
*/
|
|
37
|
+
export interface CredentialPatternsConfig {
|
|
38
|
+
/**
|
|
39
|
+
* Additional patterns appended to {@link DEFAULT_CREDENTIAL_PATTERNS}.
|
|
40
|
+
* Use for platform-specific names the defaults don't cover (e.g.
|
|
41
|
+
* `/^bearer$/i`, `/credentials/i`, `/^[a-z]+Pat$/`).
|
|
42
|
+
*/
|
|
43
|
+
extend?: RegExp[];
|
|
44
|
+
/**
|
|
45
|
+
* Replace the regex-based check entirely. Receives each property name
|
|
46
|
+
* encountered during recursion, plus the parent path. Return `true`
|
|
47
|
+
* to flag as credential-bearing. Mutually exclusive with `extend` —
|
|
48
|
+
* setting both throws at server construction.
|
|
49
|
+
*/
|
|
50
|
+
matcher?: (key: string, path: readonly string[]) => boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Per-tool override shape. Adopters specify either a mode string for
|
|
54
|
+
* coarse-grained override (`'lax'` lets every credential-shaped key
|
|
55
|
+
* through; `'authInfo-only'` rejects them all) or a granular
|
|
56
|
+
* `{ allow: [...] }` allowlist that permits specific credential paths
|
|
57
|
+
* while still rejecting unlisted ones.
|
|
58
|
+
*
|
|
59
|
+
* The `allow` shape is the recommended choice for storefronts that
|
|
60
|
+
* legitimately accept ONE specific buyer-presented credential per
|
|
61
|
+
* tool — `tools: { activate_signal: 'lax' }` opens the tool to every
|
|
62
|
+
* credential-shaped key (including `password=`, `client_secret=`),
|
|
63
|
+
* while `tools: { activate_signal: { allow: ['delivery.api_token'] } }`
|
|
64
|
+
* permits only the spec-blessed field and still rejects everything
|
|
65
|
+
* else.
|
|
66
|
+
*/
|
|
67
|
+
export type ToolCredentialPolicy = CredentialPolicyMode | {
|
|
68
|
+
readonly allow: readonly string[];
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Full credential-policy configuration. Pass a string for the simple
|
|
72
|
+
* case (`credentialPolicy: 'authInfo-only'`) or this shape for
|
|
73
|
+
* pattern customization or per-tool overrides.
|
|
74
|
+
*/
|
|
75
|
+
export interface CredentialPolicyConfig {
|
|
76
|
+
policy: CredentialPolicyMode;
|
|
77
|
+
patterns?: CredentialPatternsConfig;
|
|
78
|
+
/**
|
|
79
|
+
* Per-tool mode overrides. Storefronts that legitimately accept
|
|
80
|
+
* buyer-presented credentials on a specific tool opt that tool out
|
|
81
|
+
* of the server-wide `'authInfo-only'`:
|
|
82
|
+
*
|
|
83
|
+
* ```ts
|
|
84
|
+
* credentialPolicy: {
|
|
85
|
+
* policy: 'authInfo-only',
|
|
86
|
+
* tools: {
|
|
87
|
+
* // Coarse: lets every credential-shaped key through
|
|
88
|
+
* legacy_tool: 'lax',
|
|
89
|
+
*
|
|
90
|
+
* // Granular: only the listed paths are allowlisted; other
|
|
91
|
+
* // credential-shaped keys still reject. Recommended for
|
|
92
|
+
* // tools where the legitimate buyer-presented credential is
|
|
93
|
+
* // a known, named field.
|
|
94
|
+
* activate_signal: { allow: ['delivery.api_token'] },
|
|
95
|
+
* },
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*
|
|
99
|
+
* Allowlist entries are exact path matches against the
|
|
100
|
+
* dot-notation path the scanner emits — e.g. `'snap_access_token'`
|
|
101
|
+
* (top-level), `'context.linkedin_access_token'` (nested),
|
|
102
|
+
* `'packages.0.extra.tiktok_access_token'` (array element).
|
|
103
|
+
*/
|
|
104
|
+
tools?: Record<string, ToolCredentialPolicy>;
|
|
105
|
+
/**
|
|
106
|
+
* Extend the credential-shaped-key scan to cover `ctx.authInfo.extra`
|
|
107
|
+
* in addition to the buyer args bag. Default `false`.
|
|
108
|
+
*
|
|
109
|
+
* Custom authenticators that stamp values into `authInfo.extra` (token
|
|
110
|
+
* introspection responses, JWT claim sets, OAuth scope blobs) are
|
|
111
|
+
* outside L1's args-bag scan. Adopter handler code that reads
|
|
112
|
+
* `ctx.authInfo.extra.<credential>` for upstream auth produces a
|
|
113
|
+
* silent leak surface: a buggy `BuyerAgentRegistry.resolve` factory
|
|
114
|
+
* that throws an error embedding `extra` lands the value in
|
|
115
|
+
* `logger.error` before `redactCredentialPatterns` (which only catches
|
|
116
|
+
* labeled `Bearer <token>` shapes and ≥32-char base64 blobs) could
|
|
117
|
+
* mask it.
|
|
118
|
+
*
|
|
119
|
+
* Orthogonal to {@link policy} — adopters can mix-and-match. Common
|
|
120
|
+
* shapes:
|
|
121
|
+
*
|
|
122
|
+
* - `policy: 'authInfo-only', scanAuthInfo: true` — strictest.
|
|
123
|
+
* - `policy: 'lax', scanAuthInfo: true` — trust args, defend log
|
|
124
|
+
* propagation of authInfo extras.
|
|
125
|
+
* - `policy: 'authInfo-only', scanAuthInfo: false` — current default
|
|
126
|
+
* if `scanAuthInfo` is omitted; args-only enforcement.
|
|
127
|
+
*
|
|
128
|
+
* **Default `false` is deliberate.** OAuth introspection blobs and
|
|
129
|
+
* JWT claims in `extra` will false-positive on default patterns
|
|
130
|
+
* like `/_token$/i` (e.g. `id_token`, `access_token` claims that
|
|
131
|
+
* the framework's authenticator legitimately stamps).
|
|
132
|
+
*
|
|
133
|
+
* **Wire-envelope discipline.** Args-bag hits are reported in
|
|
134
|
+
* `details.credential_paths` (the buyer already sent these — no
|
|
135
|
+
* info disclosure). `authInfo.extra` hits are NOT reported on
|
|
136
|
+
* the wire; they're logged server-side only. Returning paths
|
|
137
|
+
* to the buyer would create a probing oracle for the structure
|
|
138
|
+
* of `authInfo.extra` (an internal value the buyer has no read
|
|
139
|
+
* access to). The wire envelope reports a coarse signal —
|
|
140
|
+
* `details.scope: 'credentials'` plus a generic message —
|
|
141
|
+
* without enumerating which `extra` field tripped the scan.
|
|
142
|
+
*
|
|
143
|
+
* See adcontextprotocol/adcp-client#1539.
|
|
144
|
+
*/
|
|
145
|
+
scanAuthInfo?: boolean;
|
|
146
|
+
}
|
|
147
|
+
export type CredentialPolicy = CredentialPolicyMode | CredentialPolicyConfig;
|
|
148
|
+
/**
|
|
149
|
+
* Default credential-name patterns. Catches the three vectors observed
|
|
150
|
+
* in PR scope3data/agentic-adapters#248 plus the broader credential
|
|
151
|
+
* vocabulary common in TS ecosystems and HTTPSig / OAuth flows.
|
|
152
|
+
* Adopters whose platform names fall outside this set extend via
|
|
153
|
+
* {@link CredentialPatternsConfig.extend}.
|
|
154
|
+
*
|
|
155
|
+
* Coverage:
|
|
156
|
+
* - `_token$` (case-insensitive) — `*_access_token`, `bearer_token`,
|
|
157
|
+
* `id_token`, `session_token`, `auth_token`, `refresh_token`.
|
|
158
|
+
* - `_secret$` / `_password$` — `client_secret`, `db_password`.
|
|
159
|
+
* - `api[_-]?key` (case-insensitive) — `api_key`, `apiKey`, `api-key`,
|
|
160
|
+
* and prefixed variants like `criteo_api_key`.
|
|
161
|
+
* - `private[_-]?key` (case-insensitive) — `private_key`, `privateKey`,
|
|
162
|
+
* `private-key`. Common in JWT / RFC 9421 signing-key flows.
|
|
163
|
+
* - `^authorization$` / `^cookie$` (case-insensitive) — HTTP-header
|
|
164
|
+
* value smuggled as a field.
|
|
165
|
+
* - `^bearer$` — bare `bearer` field.
|
|
166
|
+
* - `^accessToken$` / `^refreshToken$` (case-insensitive) — camelCase
|
|
167
|
+
* and PascalCase exact matches.
|
|
168
|
+
*
|
|
169
|
+
* Intentionally excluded from defaults (too many false positives):
|
|
170
|
+
* - bare `key` / `principal` / `kid` / `pat` — too short to risk
|
|
171
|
+
* matching legitimate routing fields.
|
|
172
|
+
* - `*Token$` PascalCase suffix without a known prefix — e.g.
|
|
173
|
+
* `paymentToken` could be a legitimate wire field. Adopters who
|
|
174
|
+
* want broader coverage extend.
|
|
175
|
+
*/
|
|
176
|
+
export declare const DEFAULT_CREDENTIAL_PATTERNS: readonly RegExp[];
|
|
177
|
+
/**
|
|
178
|
+
* Recursively scan `value` for credential-shaped keys. Returns dotted
|
|
179
|
+
* paths to every match (e.g. `['snap_access_token',
|
|
180
|
+
* 'context.snap_access_token', 'ext.snap_access_token']`). Empty array
|
|
181
|
+
* means clean.
|
|
182
|
+
*
|
|
183
|
+
* Scope:
|
|
184
|
+
* - Walks own string-keyed data properties only. Symbol keys,
|
|
185
|
+
* prototype-chain inherited properties, and accessor (getter/setter)
|
|
186
|
+
* properties are skipped — JSON-derived inputs (the only source the
|
|
187
|
+
* framework dispatches) cannot carry any of those. Hand-built
|
|
188
|
+
* objects with credential-named getters are still flagged
|
|
189
|
+
* fail-closed (the property name is matched against the regex
|
|
190
|
+
* set), but the getter is never invoked, so a throwing or
|
|
191
|
+
* side-effecting getter cannot reach the dispatcher.
|
|
192
|
+
* - Walks both plain objects and arrays; array indices appear as
|
|
193
|
+
* numeric path segments.
|
|
194
|
+
* - Stops at primitives.
|
|
195
|
+
* - Cycle-safe via a `WeakSet` tracking visited objects.
|
|
196
|
+
*/
|
|
197
|
+
export declare function scanArgsForCredentials(value: unknown, patterns?: CredentialPatternsConfig): string[];
|
|
198
|
+
/**
|
|
199
|
+
* Normalize a `CredentialPolicy` (string or object) plus a tool name
|
|
200
|
+
* to the effective {@link ToolCredentialPolicy} for that tool —
|
|
201
|
+
* either a mode string or an `{ allow: [...] }` allowlist. Per-tool
|
|
202
|
+
* overrides win; otherwise the server-wide policy applies.
|
|
203
|
+
*
|
|
204
|
+
* Caller dispatch:
|
|
205
|
+
*
|
|
206
|
+
* ```ts
|
|
207
|
+
* const effective = resolveCredentialPolicyForTool(policy, toolName);
|
|
208
|
+
* if (effective === 'lax') return; // skip scan
|
|
209
|
+
* const hits = scanArgsForCredentials(args, patterns);
|
|
210
|
+
* if (typeof effective === 'object') {
|
|
211
|
+
* // Granular allow — filter hits by the allowlist
|
|
212
|
+
* const blocked = hits.filter(p => !effective.allow.includes(p));
|
|
213
|
+
* if (blocked.length > 0) reject(blocked);
|
|
214
|
+
* } else {
|
|
215
|
+
* // 'authInfo-only' — every hit blocks
|
|
216
|
+
* if (hits.length > 0) reject(hits);
|
|
217
|
+
* }
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
export declare function resolveCredentialPolicyForTool(policy: CredentialPolicy | undefined, toolName: string): ToolCredentialPolicy;
|
|
221
|
+
//# sourceMappingURL=credential-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-policy.d.ts","sourceRoot":"","sources":["../../../src/lib/server/credential-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,eAAe,CAAC;AAE3D;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC;CAC7D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,oBAAoB,GAAG,oBAAoB,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAEhG;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,QAAQ,CAAC,EAAE,wBAAwB,CAAC;IACpC;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GAAG,sBAAsB,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAWvD,CAAC;AAmCH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,wBAAwB,GAAG,MAAM,EAAE,CAqDpG;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,QAAQ,EAAE,MAAM,GACf,oBAAoB,CAItB"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Credential discipline at the request boundary.
|
|
4
|
+
*
|
|
5
|
+
* Scans incoming buyer args for credential-shaped keys at any depth and
|
|
6
|
+
* rejects with `INVALID_REQUEST` when `credentialPolicy === 'authInfo-only'`.
|
|
7
|
+
* Closes the bug class observed in storefront fan-out paths where buyer-
|
|
8
|
+
* supplied keys like `<platform>_access_token` (top-level, in `context`,
|
|
9
|
+
* or in `ext`) flow through to upstream calls.
|
|
10
|
+
*
|
|
11
|
+
* Default mode is `'lax'` for back-compat. Opt into `'authInfo-only'` to
|
|
12
|
+
* enforce: credentials must arrive on `authInfo` (the framework-resolved
|
|
13
|
+
* bearer / signature / OAuth principal) and never on the args bag.
|
|
14
|
+
*
|
|
15
|
+
* Pattern set is extensible. Adopters whose platform vocabulary uses
|
|
16
|
+
* additional credential names extend via `credentialPolicy.patterns.extend`
|
|
17
|
+
* or replace the matcher entirely. Per-tool opt-out via
|
|
18
|
+
* `credentialPolicy.tools`.
|
|
19
|
+
*
|
|
20
|
+
* @see {@link AdcpServerConfig.credentialPolicy}
|
|
21
|
+
* @see docs/guides/CTX-METADATA-SAFETY.md
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.DEFAULT_CREDENTIAL_PATTERNS = void 0;
|
|
25
|
+
exports.scanArgsForCredentials = scanArgsForCredentials;
|
|
26
|
+
exports.resolveCredentialPolicyForTool = resolveCredentialPolicyForTool;
|
|
27
|
+
exports.validateCredentialPolicy = validateCredentialPolicy;
|
|
28
|
+
/**
|
|
29
|
+
* Default credential-name patterns. Catches the three vectors observed
|
|
30
|
+
* in PR scope3data/agentic-adapters#248 plus the broader credential
|
|
31
|
+
* vocabulary common in TS ecosystems and HTTPSig / OAuth flows.
|
|
32
|
+
* Adopters whose platform names fall outside this set extend via
|
|
33
|
+
* {@link CredentialPatternsConfig.extend}.
|
|
34
|
+
*
|
|
35
|
+
* Coverage:
|
|
36
|
+
* - `_token$` (case-insensitive) — `*_access_token`, `bearer_token`,
|
|
37
|
+
* `id_token`, `session_token`, `auth_token`, `refresh_token`.
|
|
38
|
+
* - `_secret$` / `_password$` — `client_secret`, `db_password`.
|
|
39
|
+
* - `api[_-]?key` (case-insensitive) — `api_key`, `apiKey`, `api-key`,
|
|
40
|
+
* and prefixed variants like `criteo_api_key`.
|
|
41
|
+
* - `private[_-]?key` (case-insensitive) — `private_key`, `privateKey`,
|
|
42
|
+
* `private-key`. Common in JWT / RFC 9421 signing-key flows.
|
|
43
|
+
* - `^authorization$` / `^cookie$` (case-insensitive) — HTTP-header
|
|
44
|
+
* value smuggled as a field.
|
|
45
|
+
* - `^bearer$` — bare `bearer` field.
|
|
46
|
+
* - `^accessToken$` / `^refreshToken$` (case-insensitive) — camelCase
|
|
47
|
+
* and PascalCase exact matches.
|
|
48
|
+
*
|
|
49
|
+
* Intentionally excluded from defaults (too many false positives):
|
|
50
|
+
* - bare `key` / `principal` / `kid` / `pat` — too short to risk
|
|
51
|
+
* matching legitimate routing fields.
|
|
52
|
+
* - `*Token$` PascalCase suffix without a known prefix — e.g.
|
|
53
|
+
* `paymentToken` could be a legitimate wire field. Adopters who
|
|
54
|
+
* want broader coverage extend.
|
|
55
|
+
*/
|
|
56
|
+
exports.DEFAULT_CREDENTIAL_PATTERNS = Object.freeze([
|
|
57
|
+
/_token$/i,
|
|
58
|
+
/_secret$/i,
|
|
59
|
+
/_password$/i,
|
|
60
|
+
/api[_-]?key/i,
|
|
61
|
+
/private[_-]?key/i,
|
|
62
|
+
/^authorization$/i,
|
|
63
|
+
/^cookie$/i,
|
|
64
|
+
/^bearer$/i,
|
|
65
|
+
/^accessToken$/i,
|
|
66
|
+
/^refreshToken$/i,
|
|
67
|
+
]);
|
|
68
|
+
/**
|
|
69
|
+
* Strip `/g` and `/y` flags from a regex. With those flags set,
|
|
70
|
+
* `RegExp.prototype.test` advances `lastIndex`, causing alternating-skip
|
|
71
|
+
* behavior on repeated calls against the same pattern instance. The
|
|
72
|
+
* scanner calls `.test()` per key per request and reuses the regex
|
|
73
|
+
* instance across calls, so `/credentials/gi` (a natural footgun) would
|
|
74
|
+
* produce non-deterministic hits. Strip the offending flags rather than
|
|
75
|
+
* forcing adopters to read a footnote.
|
|
76
|
+
*/
|
|
77
|
+
function stripStatefulFlags(rx) {
|
|
78
|
+
if (!rx.global && !rx.sticky)
|
|
79
|
+
return rx;
|
|
80
|
+
return new RegExp(rx.source, rx.flags.replace(/[gy]/g, ''));
|
|
81
|
+
}
|
|
82
|
+
function buildMatcher(patterns) {
|
|
83
|
+
if (patterns?.matcher && patterns.extend) {
|
|
84
|
+
throw new Error('createAdcpServer: credentialPolicy.patterns cannot set both `matcher` and `extend`. ' +
|
|
85
|
+
'`matcher` fully replaces the regex-based check; `extend` adds to the default set. ' +
|
|
86
|
+
'Pick one — they answer different questions and combining them silently drops the regex set.');
|
|
87
|
+
}
|
|
88
|
+
if (patterns?.matcher) {
|
|
89
|
+
return patterns.matcher;
|
|
90
|
+
}
|
|
91
|
+
const regexes = patterns?.extend
|
|
92
|
+
? [...exports.DEFAULT_CREDENTIAL_PATTERNS, ...patterns.extend.map(stripStatefulFlags)]
|
|
93
|
+
: exports.DEFAULT_CREDENTIAL_PATTERNS;
|
|
94
|
+
return (key) => regexes.some(rx => rx.test(key));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Recursively scan `value` for credential-shaped keys. Returns dotted
|
|
98
|
+
* paths to every match (e.g. `['snap_access_token',
|
|
99
|
+
* 'context.snap_access_token', 'ext.snap_access_token']`). Empty array
|
|
100
|
+
* means clean.
|
|
101
|
+
*
|
|
102
|
+
* Scope:
|
|
103
|
+
* - Walks own string-keyed data properties only. Symbol keys,
|
|
104
|
+
* prototype-chain inherited properties, and accessor (getter/setter)
|
|
105
|
+
* properties are skipped — JSON-derived inputs (the only source the
|
|
106
|
+
* framework dispatches) cannot carry any of those. Hand-built
|
|
107
|
+
* objects with credential-named getters are still flagged
|
|
108
|
+
* fail-closed (the property name is matched against the regex
|
|
109
|
+
* set), but the getter is never invoked, so a throwing or
|
|
110
|
+
* side-effecting getter cannot reach the dispatcher.
|
|
111
|
+
* - Walks both plain objects and arrays; array indices appear as
|
|
112
|
+
* numeric path segments.
|
|
113
|
+
* - Stops at primitives.
|
|
114
|
+
* - Cycle-safe via a `WeakSet` tracking visited objects.
|
|
115
|
+
*/
|
|
116
|
+
function scanArgsForCredentials(value, patterns) {
|
|
117
|
+
const matcher = buildMatcher(patterns);
|
|
118
|
+
const hits = [];
|
|
119
|
+
const seen = new WeakSet();
|
|
120
|
+
const walk = (node, path) => {
|
|
121
|
+
if (node === null || typeof node !== 'object')
|
|
122
|
+
return;
|
|
123
|
+
if (seen.has(node))
|
|
124
|
+
return;
|
|
125
|
+
seen.add(node);
|
|
126
|
+
if (Array.isArray(node)) {
|
|
127
|
+
for (let i = 0; i < node.length; i++) {
|
|
128
|
+
walk(node[i], [...path, String(i)]);
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
// Use property descriptors so accessor (getter/setter) properties
|
|
133
|
+
// are visible to the scanner without invoking the getter — a
|
|
134
|
+
// throwing getter on a credential-named property would otherwise
|
|
135
|
+
// either crash the dispatcher or land the surrounding `params`
|
|
136
|
+
// object in an outer error log. Data-only inputs (JSON.parse,
|
|
137
|
+
// structured clone) never have accessor descriptors, so this is
|
|
138
|
+
// a defensive measure for hand-built test inputs and any future
|
|
139
|
+
// transport that bypasses JSON parsing.
|
|
140
|
+
let descriptors;
|
|
141
|
+
try {
|
|
142
|
+
descriptors = Object.getOwnPropertyDescriptors(node);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// Proxy-trapped property enumeration that throws — fail closed
|
|
146
|
+
// by recording the parent path as suspicious. Cannot enumerate
|
|
147
|
+
// to a finer-grained location.
|
|
148
|
+
hits.push([...path, '<unreadable>'].join('.'));
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
for (const key of Object.keys(descriptors)) {
|
|
152
|
+
const desc = descriptors[key];
|
|
153
|
+
if (desc === undefined)
|
|
154
|
+
continue;
|
|
155
|
+
const childPath = [...path, key];
|
|
156
|
+
if (matcher(key, path)) {
|
|
157
|
+
hits.push(childPath.join('.'));
|
|
158
|
+
}
|
|
159
|
+
// Only recurse into data descriptors. Accessor descriptors
|
|
160
|
+
// (no `value` slot) are flagged-by-name above but never invoked.
|
|
161
|
+
if ('value' in desc) {
|
|
162
|
+
walk(desc.value, childPath);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
walk(value, []);
|
|
167
|
+
return hits;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Normalize a `CredentialPolicy` (string or object) plus a tool name
|
|
171
|
+
* to the effective {@link ToolCredentialPolicy} for that tool —
|
|
172
|
+
* either a mode string or an `{ allow: [...] }` allowlist. Per-tool
|
|
173
|
+
* overrides win; otherwise the server-wide policy applies.
|
|
174
|
+
*
|
|
175
|
+
* Caller dispatch:
|
|
176
|
+
*
|
|
177
|
+
* ```ts
|
|
178
|
+
* const effective = resolveCredentialPolicyForTool(policy, toolName);
|
|
179
|
+
* if (effective === 'lax') return; // skip scan
|
|
180
|
+
* const hits = scanArgsForCredentials(args, patterns);
|
|
181
|
+
* if (typeof effective === 'object') {
|
|
182
|
+
* // Granular allow — filter hits by the allowlist
|
|
183
|
+
* const blocked = hits.filter(p => !effective.allow.includes(p));
|
|
184
|
+
* if (blocked.length > 0) reject(blocked);
|
|
185
|
+
* } else {
|
|
186
|
+
* // 'authInfo-only' — every hit blocks
|
|
187
|
+
* if (hits.length > 0) reject(hits);
|
|
188
|
+
* }
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
function resolveCredentialPolicyForTool(policy, toolName) {
|
|
192
|
+
if (policy === undefined)
|
|
193
|
+
return 'lax';
|
|
194
|
+
if (typeof policy === 'string')
|
|
195
|
+
return policy;
|
|
196
|
+
return policy.tools?.[toolName] ?? policy.policy;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Validate a `CredentialPolicy` at server construction. Catches typos
|
|
200
|
+
* in `tools` keys (`activte_signal` instead of `activate_signal`) and
|
|
201
|
+
* the both-`extend`-and-`matcher` config error before any traffic
|
|
202
|
+
* dispatches. Throws `Error` with a specific message; callers convert
|
|
203
|
+
* to their construction-time error envelope of choice.
|
|
204
|
+
*
|
|
205
|
+
* `knownToolNames` is the set of tool names the framework will
|
|
206
|
+
* register for this server (spec tools for the claimed specialisms +
|
|
207
|
+
* any adopter-supplied custom tools). Pass after the registration
|
|
208
|
+
* loop completes so the set is authoritative.
|
|
209
|
+
*
|
|
210
|
+
* @internal — adopters cannot construct `knownToolNames` outside the
|
|
211
|
+
* framework. The framework calls this once, late in `createAdcpServer`,
|
|
212
|
+
* after every tool (including `get_adcp_capabilities`) is registered.
|
|
213
|
+
*/
|
|
214
|
+
function validateCredentialPolicy(policy, knownToolNames) {
|
|
215
|
+
if (policy === undefined || typeof policy === 'string')
|
|
216
|
+
return;
|
|
217
|
+
// Surface the both-fields-set conflict at construction, not on the
|
|
218
|
+
// first credential-bearing request. Mirrors the runtime check in
|
|
219
|
+
// `buildMatcher` so adopters get the same diagnostic regardless of
|
|
220
|
+
// whether traffic is flowing yet.
|
|
221
|
+
if (policy.patterns?.matcher && policy.patterns?.extend) {
|
|
222
|
+
throw new Error('createAdcpServer: credentialPolicy.patterns cannot set both `matcher` and `extend`. ' +
|
|
223
|
+
'`matcher` fully replaces the regex-based check; `extend` adds to the default set. Pick one.');
|
|
224
|
+
}
|
|
225
|
+
if (!policy.tools)
|
|
226
|
+
return;
|
|
227
|
+
const unknownTools = Object.keys(policy.tools).filter(name => !knownToolNames.has(name));
|
|
228
|
+
if (unknownTools.length > 0) {
|
|
229
|
+
const known = [...knownToolNames].sort().join(', ');
|
|
230
|
+
throw new Error(`createAdcpServer: credentialPolicy.tools references unregistered tool name(s): ${unknownTools
|
|
231
|
+
.map(n => JSON.stringify(n))
|
|
232
|
+
.join(', ')}. ` +
|
|
233
|
+
`A typo in this map silently no-ops the per-tool override and the server-wide policy applies, ` +
|
|
234
|
+
`which fails-closed on tools that needed an opt-out. ` +
|
|
235
|
+
`Known tool names: ${known}.`);
|
|
236
|
+
}
|
|
237
|
+
// Validate granular allow-shape entries — each must be a non-empty
|
|
238
|
+
// array of strings. An empty `allow` is the same as 'authInfo-only'
|
|
239
|
+
// for that tool (no path is permitted) and is almost certainly a
|
|
240
|
+
// bug — surface it at construction. Non-string entries would
|
|
241
|
+
// silently never match the dotted-path strings the scanner emits.
|
|
242
|
+
for (const [toolName, toolPolicy] of Object.entries(policy.tools)) {
|
|
243
|
+
if (typeof toolPolicy === 'string')
|
|
244
|
+
continue;
|
|
245
|
+
if (!Array.isArray(toolPolicy.allow)) {
|
|
246
|
+
throw new Error(`createAdcpServer: credentialPolicy.tools[${JSON.stringify(toolName)}].allow must be an array of path strings.`);
|
|
247
|
+
}
|
|
248
|
+
if (toolPolicy.allow.length === 0) {
|
|
249
|
+
throw new Error(`createAdcpServer: credentialPolicy.tools[${JSON.stringify(toolName)}].allow is empty. ` +
|
|
250
|
+
`An empty allow list is equivalent to 'authInfo-only' for this tool — drop the entry or use the string shorthand.`);
|
|
251
|
+
}
|
|
252
|
+
const nonStrings = toolPolicy.allow.filter(p => typeof p !== 'string');
|
|
253
|
+
if (nonStrings.length > 0) {
|
|
254
|
+
throw new Error(`createAdcpServer: credentialPolicy.tools[${JSON.stringify(toolName)}].allow contains non-string entries: ` +
|
|
255
|
+
`${nonStrings.map(n => JSON.stringify(n)).join(', ')}. ` +
|
|
256
|
+
`Allowlist entries are exact-match path strings (e.g. 'context.snap_access_token').`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=credential-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-policy.js","sourceRoot":"","sources":["../../../src/lib/server/credential-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -112,6 +112,23 @@ export declare class AdcpError extends Error {
|
|
|
112
112
|
* one without going through `ctx.handoffToTask(fn)`.
|
|
113
113
|
*/
|
|
114
114
|
declare const TASK_HANDOFF_BRAND: unique symbol;
|
|
115
|
+
/**
|
|
116
|
+
* Optional overrides for `ctx.handoffToTask`.
|
|
117
|
+
*
|
|
118
|
+
* @public
|
|
119
|
+
*/
|
|
120
|
+
export interface TaskHandoffOptions {
|
|
121
|
+
/**
|
|
122
|
+
* Use this exact string as the `task_id` instead of letting the framework
|
|
123
|
+
* mint a fresh one. Required when an upstream system (or a test-controller
|
|
124
|
+
* directive such as `force_create_media_buy_arm`) has already issued the ID
|
|
125
|
+
* and the spec contract demands the response echoes it verbatim.
|
|
126
|
+
*
|
|
127
|
+
* Constraints: non-empty, ≤ 128 characters. Throws if violated.
|
|
128
|
+
* The caller is responsible for uniqueness within the account.
|
|
129
|
+
*/
|
|
130
|
+
task_id?: string;
|
|
131
|
+
}
|
|
115
132
|
/**
|
|
116
133
|
* Marker the framework recognizes as "promote this call to a task."
|
|
117
134
|
* Returned from `ctx.handoffToTask(fn)`. Type parameter `TResult` is the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-outcome.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/decisioning/async-outcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEnF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,k8BAAkB,CAAC;AAEjD,MAAM,MAAM,SAAS,GAAG,iBAAiB,CAAC;AA+B1C;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAChC,QAAQ,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAU;IACrC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;IAC5D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAGzC,IAAI,EAAE,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,EAC/B,OAAO,EAAE;QACP;;;;;WAKG;QACH,QAAQ,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;QACpD,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC;IAgBH,kFAAkF;IAClF,iBAAiB,IAAI,mBAAmB;IAYxC;;;;;;OAMG;IACM,QAAQ,IAAI,MAAM;CAG5B;AAMD;;;;GAIG;AACH,QAAA,MAAM,kBAAkB,EAAE,OAAO,MAAqD,CAAC;
|
|
1
|
+
{"version":3,"file":"async-outcome.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/decisioning/async-outcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEnF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,k8BAAkB,CAAC;AAEjD,MAAM,MAAM,SAAS,GAAG,iBAAiB,CAAC;AA+B1C;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAChC,QAAQ,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAU;IACrC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;IAC5D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAGzC,IAAI,EAAE,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,EAC/B,OAAO,EAAE;QACP;;;;;WAKG;QACH,QAAQ,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;QACpD,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC;IAgBH,kFAAkF;IAClF,iBAAiB,IAAI,mBAAmB;IAYxC;;;;;;OAMG;IACM,QAAQ,IAAI,MAAM;CAG5B;AAMD;;;;GAIG;AACH,QAAA,MAAM,kBAAkB,EAAE,OAAO,MAAqD,CAAC;AAEvF;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAiBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,WAAW,CAAC,OAAO;IAClC,QAAQ,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAC;CASrC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
|
@@ -19,7 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
19
19
|
exports.AdcpError = exports.KNOWN_ERROR_CODES = void 0;
|
|
20
20
|
exports._createTaskHandoff = _createTaskHandoff;
|
|
21
21
|
exports.isTaskHandoff = isTaskHandoff;
|
|
22
|
-
exports.
|
|
22
|
+
exports._extractHandoffEntry = _extractHandoffEntry;
|
|
23
23
|
const enums_generated_1 = require("../../types/enums.generated");
|
|
24
24
|
const error_codes_1 = require("../../types/error-codes");
|
|
25
25
|
/**
|
|
@@ -140,32 +140,34 @@ exports.AdcpError = AdcpError;
|
|
|
140
140
|
*/
|
|
141
141
|
const TASK_HANDOFF_BRAND = Symbol.for('@adcp/decisioning/task-handoff');
|
|
142
142
|
/**
|
|
143
|
-
* The handoff
|
|
144
|
-
* marker object — NOT on the marker itself.
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* type-visible field that adopters could forge with their own
|
|
143
|
+
* The handoff fn and options live in a WeakMap keyed by the `TaskHandoff`
|
|
144
|
+
* marker object — NOT on the marker itself. Both are stored atomically in a
|
|
145
|
+
* single entry so `isTaskHandoff` and `_extractHandoffEntry` always see a
|
|
146
|
+
* consistent pair. Closes round-6 CR-3 / Protocol-L2: `_taskFn` was
|
|
147
|
+
* previously a type-visible field that adopters could forge with their own
|
|
149
148
|
* `Symbol.for(...)` call.
|
|
150
149
|
*/
|
|
151
|
-
const
|
|
150
|
+
const taskHandoffEntries = new WeakMap();
|
|
152
151
|
/**
|
|
153
152
|
* Construct a `TaskHandoff<T>` marker. The framework's `ctx.handoffToTask`
|
|
154
153
|
* helper invokes this; adopters don't call it directly.
|
|
155
154
|
*
|
|
156
|
-
* The `fn`
|
|
157
|
-
* object. Adopters can hold the marker and pass it through
|
|
158
|
-
* values, but cannot extract or invoke `fn` themselves — only the
|
|
159
|
-
* framework's `
|
|
155
|
+
* The `fn` and `options` are stashed atomically in a module-private WeakMap
|
|
156
|
+
* keyed by the marker object. Adopters can hold the marker and pass it through
|
|
157
|
+
* return values, but cannot extract or invoke `fn` themselves — only the
|
|
158
|
+
* framework's `_extractHandoffEntry` can.
|
|
160
159
|
*
|
|
161
160
|
* @internal
|
|
162
161
|
*/
|
|
163
|
-
function _createTaskHandoff(fn) {
|
|
162
|
+
function _createTaskHandoff(fn, options) {
|
|
164
163
|
// Frozen object so adopters can't mutate the brand field. Even if
|
|
165
164
|
// they did, the dispatch seam keys on identity (WeakMap), not on
|
|
166
165
|
// mutable structure.
|
|
167
166
|
const marker = Object.freeze({ [TASK_HANDOFF_BRAND]: true });
|
|
168
|
-
|
|
167
|
+
taskHandoffEntries.set(marker, {
|
|
168
|
+
fn: fn,
|
|
169
|
+
options,
|
|
170
|
+
});
|
|
169
171
|
return marker;
|
|
170
172
|
}
|
|
171
173
|
/**
|
|
@@ -182,17 +184,20 @@ function isTaskHandoff(value) {
|
|
|
182
184
|
return (typeof value === 'object' &&
|
|
183
185
|
value !== null &&
|
|
184
186
|
value[TASK_HANDOFF_BRAND] === true &&
|
|
185
|
-
|
|
187
|
+
taskHandoffEntries.has(value));
|
|
186
188
|
}
|
|
187
189
|
/**
|
|
188
|
-
* Extract the handoff
|
|
190
|
+
* Extract the handoff fn and options from a marker. Framework-only — the
|
|
189
191
|
* dispatch seam in `from-platform.ts` calls this after `isTaskHandoff`.
|
|
190
192
|
* Returns `undefined` if the marker wasn't created by `_createTaskHandoff`
|
|
191
193
|
* (forgery).
|
|
192
194
|
*
|
|
193
195
|
* @internal
|
|
194
196
|
*/
|
|
195
|
-
function
|
|
196
|
-
|
|
197
|
+
function _extractHandoffEntry(handoff) {
|
|
198
|
+
const entry = taskHandoffEntries.get(handoff);
|
|
199
|
+
if (!entry)
|
|
200
|
+
return undefined;
|
|
201
|
+
return entry;
|
|
197
202
|
}
|
|
198
203
|
//# sourceMappingURL=async-outcome.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-outcome.js","sourceRoot":"","sources":["../../../../src/lib/server/decisioning/async-outcome.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;
|
|
1
|
+
{"version":3,"file":"async-outcome.js","sourceRoot":"","sources":["../../../../src/lib/server/decisioning/async-outcome.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import type { Account } from './account';
|
|
25
25
|
import type { Format, FormatReferenceStructuredObject, PropertyList, CollectionList } from '../../types/tools.generated';
|
|
26
|
-
import type { TaskHandoff, TaskHandoffContext } from './async-outcome';
|
|
26
|
+
import type { TaskHandoff, TaskHandoffContext, TaskHandoffOptions } from './async-outcome';
|
|
27
27
|
import type { CtxMetadataRef, ResourceKind } from '../ctx-metadata';
|
|
28
28
|
import type { BuyerAgent } from './buyer-agent';
|
|
29
29
|
export interface RequestContext<TAccount = Account> {
|
|
@@ -111,8 +111,14 @@ export interface RequestContext<TAccount = Account> {
|
|
|
111
111
|
* return await this.commitSync(req);
|
|
112
112
|
* }
|
|
113
113
|
* ```
|
|
114
|
+
*
|
|
115
|
+
* Pass `options.task_id` when an upstream system or test-controller directive
|
|
116
|
+
* has already issued the task id and the spec contract requires the response
|
|
117
|
+
* to echo it verbatim (e.g. `force_create_media_buy_arm`). The framework uses
|
|
118
|
+
* the supplied id instead of minting a fresh one; `taskCtx.id` reflects it.
|
|
119
|
+
* Constraints: non-empty, ≤ 128 characters. Throws if violated.
|
|
114
120
|
*/
|
|
115
|
-
handoffToTask<TResult>(fn: (taskCtx: TaskHandoffContext) => Promise<TResult
|
|
121
|
+
handoffToTask<TResult>(fn: (taskCtx: TaskHandoffContext) => Promise<TResult>, options?: TaskHandoffOptions): TaskHandoff<TResult>;
|
|
116
122
|
}
|
|
117
123
|
export interface WorkflowStateReader {
|
|
118
124
|
/**
|