@adcp/sdk 14.0.0-rc.37 → 14.0.0-rc.39
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-storyboard-summary.js +286 -0
- package/bin/adcp.js +221 -10
- package/dist/lib/conformance/schemaLoader.d.mts +1 -1
- package/dist/lib/conformance/schemaLoader.d.ts +1 -1
- package/dist/lib/core/AgentClient.d.mts +6 -1
- package/dist/lib/core/AgentClient.d.ts +6 -1
- package/dist/lib/core/AgentClient.js +9 -0
- package/dist/lib/core/AgentClient.mjs +9 -0
- package/dist/lib/core/ConversationTypes.d.mts +29 -0
- package/dist/lib/core/ConversationTypes.d.ts +29 -0
- package/dist/lib/core/SingleAgentClient.d.mts +3 -1
- package/dist/lib/core/SingleAgentClient.d.ts +3 -1
- package/dist/lib/core/SingleAgentClient.js +9 -1
- package/dist/lib/core/SingleAgentClient.mjs +9 -1
- package/dist/lib/core/TaskExecutor.d.mts +13 -1
- package/dist/lib/core/TaskExecutor.d.ts +13 -1
- package/dist/lib/core/TaskExecutor.js +216 -18
- package/dist/lib/core/TaskExecutor.mjs +216 -19
- package/dist/lib/index.d.mts +5 -2
- package/dist/lib/index.d.ts +5 -2
- package/dist/lib/index.js +10 -1
- package/dist/lib/index.mjs +10 -1
- package/dist/lib/media-buy/action-assessment.d.mts +77 -0
- package/dist/lib/media-buy/action-assessment.d.ts +77 -0
- package/dist/lib/media-buy/action-assessment.js +300 -0
- package/dist/lib/media-buy/action-assessment.mjs +284 -0
- package/dist/lib/media-buy/action-constraints.d.mts +9 -0
- package/dist/lib/media-buy/action-constraints.d.ts +9 -0
- package/dist/lib/media-buy/action-constraints.js +170 -0
- package/dist/lib/media-buy/action-constraints.mjs +146 -0
- package/dist/lib/media-buy/action-contracts.d.mts +40 -0
- package/dist/lib/media-buy/action-contracts.d.ts +40 -0
- package/dist/lib/media-buy/action-contracts.js +304 -0
- package/dist/lib/media-buy/action-contracts.mjs +267 -0
- package/dist/lib/media-buy/action-metadata.generated.d.mts +37 -0
- package/dist/lib/media-buy/action-metadata.generated.d.ts +37 -0
- package/dist/lib/media-buy/action-metadata.generated.js +128 -0
- package/dist/lib/media-buy/action-metadata.generated.mjs +101 -0
- package/dist/lib/media-buy/action-types.d.mts +106 -0
- package/dist/lib/media-buy/action-types.d.ts +106 -0
- package/dist/lib/{types/v3-1-beta/tools.generated.js → media-buy/action-types.js} +2 -2
- package/dist/lib/media-buy/actions.d.mts +6 -0
- package/dist/lib/media-buy/actions.d.ts +6 -0
- package/dist/lib/media-buy/actions.js +38 -0
- package/dist/lib/media-buy/actions.mjs +9 -0
- package/dist/lib/media-buy/available-actions.d.mts +2 -1
- package/dist/lib/media-buy/available-actions.d.ts +2 -1
- package/dist/lib/media-buy/available-actions.js +4 -3
- package/dist/lib/media-buy/available-actions.mjs +4 -3
- package/dist/lib/media-buy/compatibility.js +3 -0
- package/dist/lib/media-buy/compatibility.mjs +3 -0
- package/dist/lib/media-buy/index.d.mts +4 -0
- package/dist/lib/media-buy/index.d.ts +4 -0
- package/dist/lib/media-buy/index.js +3 -1
- package/dist/lib/media-buy/index.mjs +1 -0
- package/dist/lib/media-buy/legacy-action-ids.d.mts +1 -0
- package/dist/lib/media-buy/legacy-action-ids.d.ts +1 -0
- package/dist/lib/media-buy/legacy-action-ids.js +50 -0
- package/dist/lib/media-buy/legacy-action-ids.mjs +26 -0
- package/dist/lib/media-buy/mutations.d.mts +70 -0
- package/dist/lib/media-buy/mutations.d.ts +70 -0
- package/dist/lib/media-buy/mutations.js +525 -0
- package/dist/lib/media-buy/mutations.mjs +498 -0
- package/dist/lib/media-buy/preflight.d.mts +20 -69
- package/dist/lib/media-buy/preflight.d.ts +20 -69
- package/dist/lib/media-buy/preflight.js +100 -336
- package/dist/lib/media-buy/preflight.mjs +111 -333
- package/dist/lib/media-buy/targeting-input.d.mts +7 -4
- package/dist/lib/media-buy/targeting-input.d.ts +7 -4
- package/dist/lib/media-buy/types.d.mts +55 -7
- package/dist/lib/media-buy/types.d.ts +55 -7
- package/dist/lib/protocols/rawResponseCapture.d.mts +12 -0
- package/dist/lib/protocols/rawResponseCapture.d.ts +12 -0
- package/dist/lib/protocols/rawResponseCapture.js +33 -3
- package/dist/lib/protocols/rawResponseCapture.mjs +32 -3
- package/dist/lib/registry/types.generated.d.mts +377 -9
- package/dist/lib/registry/types.generated.d.ts +377 -9
- package/dist/lib/reporting/content-mismatch.d.mts +126 -0
- package/dist/lib/reporting/content-mismatch.d.ts +126 -0
- package/dist/lib/reporting/content-mismatch.js +90 -0
- package/dist/lib/reporting/content-mismatch.mjs +66 -0
- package/dist/lib/reporting/evidence.d.mts +1 -0
- package/dist/lib/reporting/evidence.d.ts +1 -0
- package/dist/lib/reporting/evidence.js +32 -3
- package/dist/lib/reporting/evidence.mjs +31 -3
- package/dist/lib/reporting/index.d.mts +3 -1
- package/dist/lib/reporting/index.d.ts +3 -1
- package/dist/lib/reporting/index.js +3 -0
- package/dist/lib/reporting/index.mjs +2 -0
- package/dist/lib/reporting/ledger/handler.d.mts +51 -1
- package/dist/lib/reporting/ledger/handler.d.ts +51 -1
- package/dist/lib/reporting/ledger/handler.js +306 -38
- package/dist/lib/reporting/ledger/handler.mjs +304 -37
- package/dist/lib/reporting/ledger/health.d.mts +12 -0
- package/dist/lib/reporting/ledger/health.d.ts +12 -0
- package/dist/lib/reporting/ledger/health.js +15 -2
- package/dist/lib/reporting/ledger/health.mjs +13 -1
- package/dist/lib/reporting/ledger/index.d.mts +3 -0
- package/dist/lib/reporting/ledger/index.d.ts +3 -0
- package/dist/lib/reporting/ledger/index.js +7 -1
- package/dist/lib/reporting/ledger/index.mjs +3 -0
- package/dist/lib/reporting/ledger/lifecycle.d.mts +31 -4
- package/dist/lib/reporting/ledger/lifecycle.d.ts +31 -4
- package/dist/lib/reporting/ledger/lifecycle.js +244 -37
- package/dist/lib/reporting/ledger/lifecycle.mjs +244 -37
- package/dist/lib/reporting/ledger/managed-postgres.d.mts +231 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.ts +231 -0
- package/dist/lib/reporting/ledger/managed-postgres.js +1797 -0
- package/dist/lib/reporting/ledger/managed-postgres.mjs +1776 -0
- package/dist/lib/reporting/ledger/managed.d.mts +355 -0
- package/dist/lib/reporting/ledger/managed.d.ts +355 -0
- package/dist/lib/reporting/ledger/managed.js +661 -0
- package/dist/lib/reporting/ledger/managed.mjs +633 -0
- package/dist/lib/reporting/ledger/notification-activity.d.mts +222 -0
- package/dist/lib/reporting/ledger/notification-activity.d.ts +222 -0
- package/dist/lib/reporting/ledger/notification-activity.js +1139 -0
- package/dist/lib/reporting/ledger/notification-activity.mjs +1110 -0
- package/dist/lib/reporting/ledger/postgres.d.mts +161 -1
- package/dist/lib/reporting/ledger/postgres.d.ts +161 -1
- package/dist/lib/reporting/ledger/postgres.js +1153 -21
- package/dist/lib/reporting/ledger/postgres.mjs +1152 -21
- package/dist/lib/reporting/ledger/producer.d.mts +8 -0
- package/dist/lib/reporting/ledger/producer.d.ts +8 -0
- package/dist/lib/reporting/ledger/producer.js +146 -52
- package/dist/lib/reporting/ledger/producer.mjs +146 -51
- package/dist/lib/reporting/ledger/types.d.mts +358 -1
- package/dist/lib/reporting/ledger/types.d.ts +358 -1
- package/dist/lib/reporting/ledger/types.js +3 -0
- package/dist/lib/reporting/ledger/types.mjs +2 -0
- package/dist/lib/reporting/reconciliation.d.mts +362 -2
- package/dist/lib/reporting/reconciliation.d.ts +362 -2
- package/dist/lib/reporting/reconciliation.js +1051 -7
- package/dist/lib/reporting/reconciliation.mjs +1053 -7
- package/dist/lib/reporting/service/conformance.d.mts +35 -0
- package/dist/lib/reporting/service/conformance.d.ts +35 -0
- package/dist/lib/reporting/service/conformance.js +89 -0
- package/dist/lib/reporting/service/conformance.mjs +68 -0
- package/dist/lib/reporting/service/index.d.mts +182 -0
- package/dist/lib/reporting/service/index.d.ts +182 -0
- package/dist/lib/reporting/service/index.js +793 -0
- package/dist/lib/reporting/service/index.mjs +787 -0
- package/dist/lib/reporting/source/index.d.mts +2 -1
- package/dist/lib/reporting/source/index.d.ts +2 -1
- package/dist/lib/reporting/source/index.js +16 -3
- package/dist/lib/reporting/source/index.mjs +12 -1
- package/dist/lib/reporting/source/inline.d.mts +88 -1
- package/dist/lib/reporting/source/inline.d.ts +88 -1
- package/dist/lib/reporting/source/inline.js +1161 -163
- package/dist/lib/reporting/source/inline.mjs +1166 -163
- package/dist/lib/reporting/source/manifest.js +12 -7
- package/dist/lib/reporting/source/manifest.mjs +12 -7
- package/dist/lib/reporting/source/source.d.mts +26 -0
- package/dist/lib/reporting/source/source.d.ts +26 -0
- package/dist/lib/reporting/source/source.js +71 -2
- package/dist/lib/reporting/source/source.mjs +65 -1
- package/dist/lib/schemas/index.d.mts +22 -1
- package/dist/lib/schemas/index.d.ts +22 -1
- package/dist/lib/schemas/index.js +7 -0
- package/dist/lib/schemas/index.mjs +7 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/create-adcp-server.d.mts +18 -0
- package/dist/lib/server/create-adcp-server.d.ts +18 -0
- package/dist/lib/server/create-adcp-server.js +52 -2
- package/dist/lib/server/create-adcp-server.mjs +52 -2
- package/dist/lib/server/decisioning/account.d.mts +1 -1
- package/dist/lib/server/decisioning/account.d.ts +1 -1
- package/dist/lib/server/decisioning/index.d.mts +1 -0
- package/dist/lib/server/decisioning/index.d.ts +1 -0
- package/dist/lib/server/decisioning/platform.d.mts +3 -0
- package/dist/lib/server/decisioning/platform.d.ts +3 -0
- package/dist/lib/server/decisioning/runtime/from-platform.js +88 -10
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +88 -10
- package/dist/lib/server/decisioning/specialisms/reporting.d.mts +38 -0
- package/dist/lib/server/decisioning/specialisms/reporting.d.ts +38 -0
- package/dist/lib/{types/v3-1-beta/index.js → server/decisioning/specialisms/reporting.js} +2 -8
- package/dist/lib/server/decisioning/specialisms/reporting.mjs +0 -0
- package/dist/lib/server/index.d.mts +4 -2
- package/dist/lib/server/index.d.ts +4 -2
- package/dist/lib/server/index.js +5 -0
- package/dist/lib/server/index.mjs +4 -0
- package/dist/lib/server/media-buy-action-resolver.d.mts +63 -0
- package/dist/lib/server/media-buy-action-resolver.d.ts +63 -0
- package/dist/lib/server/media-buy-action-resolver.js +297 -0
- package/dist/lib/server/media-buy-action-resolver.mjs +285 -0
- package/dist/lib/server/media-buy-actions.d.mts +7 -8
- package/dist/lib/server/media-buy-actions.d.ts +7 -8
- package/dist/lib/server/media-buy-actions.js +57 -14
- package/dist/lib/server/media-buy-actions.mjs +63 -14
- package/dist/lib/server/notification-subscriptions/index.d.mts +2 -2
- package/dist/lib/server/notification-subscriptions/index.d.ts +2 -2
- package/dist/lib/server/notification-subscriptions/index.js +2 -0
- package/dist/lib/server/notification-subscriptions/index.mjs +2 -0
- package/dist/lib/server/notification-subscriptions/postgres-runtime.d.mts +3 -1
- package/dist/lib/server/notification-subscriptions/postgres-runtime.d.ts +3 -1
- package/dist/lib/server/notification-subscriptions/postgres-runtime.js +1 -0
- package/dist/lib/server/notification-subscriptions/postgres-runtime.mjs +1 -0
- package/dist/lib/server/notification-subscriptions/runtime.d.mts +12 -1
- package/dist/lib/server/notification-subscriptions/runtime.d.ts +12 -1
- package/dist/lib/server/notification-subscriptions/runtime.js +102 -16
- package/dist/lib/server/notification-subscriptions/runtime.mjs +101 -16
- package/dist/lib/server/notification-subscriptions/types.d.mts +104 -1
- package/dist/lib/server/notification-subscriptions/types.d.ts +104 -1
- package/dist/lib/server/webhook-emitter.d.mts +40 -5
- package/dist/lib/server/webhook-emitter.d.ts +40 -5
- package/dist/lib/server/webhook-emitter.js +23 -12
- package/dist/lib/server/webhook-emitter.mjs +23 -12
- package/dist/lib/storage/interfaces.d.mts +14 -2
- package/dist/lib/storage/interfaces.d.ts +14 -2
- package/dist/lib/testing/compliance/comply.d.mts +9 -3
- package/dist/lib/testing/compliance/comply.d.ts +9 -3
- package/dist/lib/testing/compliance/comply.js +158 -3
- package/dist/lib/testing/compliance/comply.mjs +159 -4
- package/dist/lib/testing/compliance/storyboard-tracks.js +7 -5
- package/dist/lib/testing/compliance/storyboard-tracks.mjs +7 -5
- package/dist/lib/testing/compliance/summary.js +10 -1
- package/dist/lib/testing/compliance/summary.mjs +10 -1
- package/dist/lib/testing/index.d.mts +1 -1
- package/dist/lib/testing/index.d.ts +1 -1
- package/dist/lib/testing/index.js +2 -0
- package/dist/lib/testing/index.mjs +3 -1
- package/dist/lib/testing/storyboard/agent-routing.d.mts +12 -43
- package/dist/lib/testing/storyboard/agent-routing.d.ts +12 -43
- package/dist/lib/testing/storyboard/agent-routing.js +75 -13
- package/dist/lib/testing/storyboard/agent-routing.mjs +70 -12
- package/dist/lib/testing/storyboard/index.d.mts +1 -0
- package/dist/lib/testing/storyboard/index.d.ts +1 -0
- package/dist/lib/testing/storyboard/index.js +3 -0
- package/dist/lib/testing/storyboard/index.mjs +2 -0
- package/dist/lib/testing/storyboard/junit.d.mts +1 -1
- package/dist/lib/testing/storyboard/junit.d.ts +1 -1
- package/dist/lib/testing/storyboard/junit.js +21 -2
- package/dist/lib/testing/storyboard/junit.mjs +21 -2
- package/dist/lib/testing/storyboard/probes.d.mts +130 -0
- package/dist/lib/testing/storyboard/probes.d.ts +130 -0
- package/dist/lib/testing/storyboard/probes.js +682 -10
- package/dist/lib/testing/storyboard/probes.mjs +683 -3
- package/dist/lib/testing/storyboard/request-signing/builder.d.mts +16 -5
- package/dist/lib/testing/storyboard/request-signing/builder.d.ts +16 -5
- package/dist/lib/testing/storyboard/request-signing/grader.d.mts +44 -1
- package/dist/lib/testing/storyboard/request-signing/grader.d.ts +44 -1
- package/dist/lib/testing/storyboard/request-signing/grader.js +46 -22
- package/dist/lib/testing/storyboard/request-signing/grader.mjs +43 -21
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.mts +86 -11
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.ts +86 -11
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.js +119 -25
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +117 -26
- package/dist/lib/testing/storyboard/request-signing/synthesize.js +22 -2
- package/dist/lib/testing/storyboard/request-signing/synthesize.mjs +22 -2
- package/dist/lib/testing/storyboard/runner.d.mts +103 -0
- package/dist/lib/testing/storyboard/runner.d.ts +103 -0
- package/dist/lib/testing/storyboard/runner.js +1090 -268
- package/dist/lib/testing/storyboard/runner.mjs +1096 -261
- package/dist/lib/testing/storyboard/seeding.d.mts +4 -1
- package/dist/lib/testing/storyboard/seeding.d.ts +4 -1
- package/dist/lib/testing/storyboard/seeding.js +55 -24
- package/dist/lib/testing/storyboard/seeding.mjs +55 -24
- package/dist/lib/testing/storyboard/test-kit.d.mts +37 -3
- package/dist/lib/testing/storyboard/test-kit.d.ts +37 -3
- package/dist/lib/testing/storyboard/test-kit.js +8 -2
- package/dist/lib/testing/storyboard/test-kit.mjs +7 -2
- package/dist/lib/testing/storyboard/types.d.mts +132 -10
- package/dist/lib/testing/storyboard/types.d.ts +132 -10
- package/dist/lib/testing/storyboard/types.js +17 -0
- package/dist/lib/testing/storyboard/types.mjs +16 -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 +16 -0
- package/dist/lib/testing/storyboard/validations.mjs +16 -0
- package/dist/lib/testing/test-controller.d.mts +1 -1
- package/dist/lib/testing/test-controller.d.ts +1 -1
- package/dist/lib/types/buy-products.d.ts +71 -6
- package/dist/lib/types/control-media-buy.d.ts +25 -11
- package/dist/lib/types/core.generated.d.mts +69 -10
- package/dist/lib/types/core.generated.d.ts +69 -10
- package/dist/lib/types/create-media-buy.d.ts +71 -6
- package/dist/lib/types/forward-compat-error-codes.d.mts +7 -6
- package/dist/lib/types/forward-compat-error-codes.d.ts +7 -6
- package/dist/lib/types/index.d.mts +2 -2
- package/dist/lib/types/index.d.ts +2 -2
- package/dist/lib/types/schemas.generated.d.ts +8040 -8116
- package/dist/lib/types/schemas.generated.js +1074 -309
- package/dist/lib/types/schemas.generated.mjs +1068 -309
- package/dist/lib/types/tools.generated.d.mts +65 -6
- package/dist/lib/types/tools.generated.d.ts +65 -6
- package/dist/lib/types/update-media-buy.d.ts +71 -6
- package/dist/lib/utils/redact-secrets.d.mts +1 -1
- package/dist/lib/utils/redact-secrets.d.ts +1 -1
- package/dist/lib/utils/redact-secrets.js +1 -1
- package/dist/lib/utils/redact-secrets.mjs +1 -1
- package/dist/lib/v2/projection/cache-versions.d.mts +0 -1
- package/dist/lib/v2/projection/cache-versions.d.ts +0 -1
- package/dist/lib/v2/projection/cache-versions.js +1 -15
- package/dist/lib/v2/projection/cache-versions.mjs +1 -14
- package/dist/lib/v2/projection/canonical-properties.js +2 -2
- package/dist/lib/v2/projection/canonical-properties.mjs +3 -3
- package/dist/lib/v2/projection/registry.d.mts +1 -1
- package/dist/lib/v2/projection/registry.d.ts +1 -1
- package/dist/lib/v2/projection/registry.js +2 -2
- package/dist/lib/v2/projection/registry.mjs +3 -3
- package/dist/lib/validation/schema-loader.d.mts +9 -1
- package/dist/lib/validation/schema-loader.d.ts +9 -1
- package/dist/lib/validation/schema-loader.js +65 -8
- package/dist/lib/validation/schema-loader.mjs +64 -8
- package/dist/lib/version.d.mts +5 -5
- package/dist/lib/version.d.ts +5 -5
- package/dist/lib/version.js +3 -8
- package/dist/lib/version.mjs +3 -8
- package/dist/lib/wholesale-feed-sync/index.d.mts +1 -0
- package/dist/lib/wholesale-feed-sync/index.d.ts +1 -0
- package/dist/lib/wholesale-feed-sync/protocol-types.d.mts +42 -0
- package/dist/lib/wholesale-feed-sync/protocol-types.d.ts +42 -0
- package/dist/lib/wholesale-feed-sync/protocol-types.js +16 -0
- package/dist/lib/wholesale-feed-sync/protocol-types.mjs +0 -0
- package/dist/lib/wholesale-feed-sync/sync.d.mts +6 -6
- package/dist/lib/wholesale-feed-sync/sync.d.ts +6 -6
- package/dist/lib/wholesale-feed-sync/sync.js +3 -1
- package/dist/lib/wholesale-feed-sync/sync.mjs +3 -1
- package/dist/lib/wholesale-feed-sync/types.d.mts +15 -14
- package/dist/lib/wholesale-feed-sync/types.d.ts +15 -14
- package/dist/lib/wholesale-feed-sync/webhook-notification.d.mts +7 -5
- package/dist/lib/wholesale-feed-sync/webhook-notification.d.ts +7 -5
- package/dist/lib/wholesale-feed-sync/webhook-notification.js +45 -0
- package/dist/lib/wholesale-feed-sync/webhook-notification.mjs +44 -0
- package/docs/CLI.md +1 -1
- package/docs/TYPE-SUMMARY.md +118 -4
- package/docs/guides/ASYNC-API-REFERENCE.md +62 -1
- package/docs/guides/ASYNC-DEVELOPER-GUIDE.md +25 -0
- package/docs/guides/ASYNC-DOCUMENTATION-INDEX.md +3 -0
- package/docs/guides/BUYER-QUICKSTART-3.2.md +5 -0
- package/docs/guides/DURABLE-BUYER-WRITES.md +337 -0
- package/docs/guides/EXISTING-PLATFORM.md +80 -1
- package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +57 -0
- package/docs/guides/MEDIA-BUY-ACTION-ASSESSMENT.md +300 -0
- package/docs/guides/REPORTING-LEDGER.md +654 -3
- package/docs/guides/REPORTING-RECONCILIATION.md +50 -0
- package/docs/guides/REPORTING-SOURCE-EXECUTOR.md +63 -1
- package/docs/guides/SELLER-QUICKSTART-3.2.md +2 -0
- package/docs/guides/VALIDATE-YOUR-AGENT.md +35 -0
- package/docs/guides/idempotency-crash-recovery.md +4 -0
- package/docs/llms.txt +4 -2
- package/docs/migration-14.x-rc-worksheet.md +60 -5
- package/docs/migration-7.9-to-7.10.md +7 -5
- package/examples/README.md +17 -0
- package/examples/durable-buyer-writes/caller.ts +745 -0
- package/examples/durable-buyer-writes/worker.ts +240 -0
- package/examples/reliable-reporting-service/README.md +100 -0
- package/examples/seller-3.2-starter.ts +7 -8
- package/examples/targeting-input-existing-platform.ts +153 -0
- package/package.json +41 -29
- package/skills/build-seller-agent/SKILL.md +2 -0
- package/skills/build-seller-agent/specialisms/signed-requests.md +11 -1
- package/skills/cross-cutting.md +28 -11
- package/compliance/cache/3.1.0-beta.7/domains/brand/index.yaml +0 -160
- package/compliance/cache/3.1.0-beta.7/domains/brand/scenarios/distributed_brand_resolution.yaml +0 -415
- package/compliance/cache/3.1.0-beta.7/domains/brand/scenarios/single_side_trust_extension.yaml +0 -454
- package/compliance/cache/3.1.0-beta.7/domains/creative/index.yaml +0 -339
- package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/billing_out_of_band.yaml +0 -153
- package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/creative_lifecycle_webhooks.yaml +0 -389
- package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/native_in_feed.yaml +0 -543
- package/compliance/cache/3.1.0-beta.7/domains/governance/index.yaml +0 -682
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/index.yaml +0 -781
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/audience_buy_flow.yaml +0 -380
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/available_actions.yaml +0 -565
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/billing_finality_delivery.yaml +0 -354
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/canonical_formats.yaml +0 -711
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/clicks_buy_flow.yaml +0 -264
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/completed_views_buy_flow.yaml +0 -344
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/create_media_buy_async.yaml +0 -234
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +0 -419
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/creative_reception.yaml +0 -247
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/delivery_reporting.yaml +0 -357
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/dependency_impairment.yaml +0 -633
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/dependency_impairment_cardinality.yaml +0 -800
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/event_dedup_flow.yaml +0 -399
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/frequency_cap_enforcement.yaml +0 -309
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_approved.yaml +0 -214
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_conditions.yaml +0 -199
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_denied.yaml +0 -204
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_denied_recovery.yaml +0 -252
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/invalid_transitions.yaml +0 -289
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/inventory_list_no_match.yaml +0 -148
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/inventory_list_targeting.yaml +0 -276
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/measurement_accountability.yaml +0 -244
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/measurement_terms_rejected.yaml +0 -203
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/pending_creatives_to_start.yaml +0 -274
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/per_creative_conversion_attribution.yaml +0 -500
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/performance_buy_flow.yaml +0 -428
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/performance_buy_flow_roas.yaml +0 -470
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/product_signal_targeting.yaml +0 -373
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_finalize.yaml +0 -399
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_finalize_asap_timing.yaml +0 -264
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_not_found_errors.yaml +0 -257
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_audit_observation.yaml +0 -333
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_enforcement.yaml +0 -517
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_truth_of_claim.yaml +0 -294
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/reach_buy_flow.yaml +0 -823
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/refine_finalize_exclusivity.yaml +0 -360
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/refine_products.yaml +0 -148
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_accountability.yaml +0 -293
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +0 -307
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_optimization_flow.yaml +0 -576
- package/compliance/cache/3.1.0-beta.7/domains/media-buy/state-machine.yaml +0 -442
- package/compliance/cache/3.1.0-beta.7/domains/signals/index.yaml +0 -266
- package/compliance/cache/3.1.0-beta.7/domains/sponsored-intelligence/index.yaml +0 -256
- package/compliance/cache/3.1.0-beta.7/index.json +0 -356
- package/compliance/cache/3.1.0-beta.7/protocols/brand/index.yaml +0 -160
- package/compliance/cache/3.1.0-beta.7/protocols/brand/scenarios/distributed_brand_resolution.yaml +0 -415
- package/compliance/cache/3.1.0-beta.7/protocols/brand/scenarios/single_side_trust_extension.yaml +0 -454
- package/compliance/cache/3.1.0-beta.7/protocols/creative/index.yaml +0 -339
- package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/billing_out_of_band.yaml +0 -153
- package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/creative_lifecycle_webhooks.yaml +0 -389
- package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/native_in_feed.yaml +0 -543
- package/compliance/cache/3.1.0-beta.7/protocols/governance/index.yaml +0 -682
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/index.yaml +0 -781
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/audience_buy_flow.yaml +0 -380
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/available_actions.yaml +0 -565
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/billing_finality_delivery.yaml +0 -354
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/canonical_formats.yaml +0 -711
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/clicks_buy_flow.yaml +0 -264
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/completed_views_buy_flow.yaml +0 -344
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/create_media_buy_async.yaml +0 -234
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +0 -419
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/creative_reception.yaml +0 -247
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/delivery_reporting.yaml +0 -357
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/dependency_impairment.yaml +0 -633
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/dependency_impairment_cardinality.yaml +0 -800
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/event_dedup_flow.yaml +0 -399
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/frequency_cap_enforcement.yaml +0 -309
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_approved.yaml +0 -214
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_conditions.yaml +0 -199
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_denied.yaml +0 -204
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_denied_recovery.yaml +0 -252
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/invalid_transitions.yaml +0 -289
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/inventory_list_no_match.yaml +0 -148
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/inventory_list_targeting.yaml +0 -276
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/measurement_accountability.yaml +0 -244
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +0 -203
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +0 -274
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/per_creative_conversion_attribution.yaml +0 -500
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/performance_buy_flow.yaml +0 -428
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/performance_buy_flow_roas.yaml +0 -470
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/product_signal_targeting.yaml +0 -373
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_finalize.yaml +0 -399
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_finalize_asap_timing.yaml +0 -264
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_not_found_errors.yaml +0 -257
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_audit_observation.yaml +0 -333
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_enforcement.yaml +0 -517
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_truth_of_claim.yaml +0 -294
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/reach_buy_flow.yaml +0 -823
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml +0 -360
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/refine_products.yaml +0 -148
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_accountability.yaml +0 -293
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +0 -307
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml +0 -576
- package/compliance/cache/3.1.0-beta.7/protocols/media-buy/state-machine.yaml +0 -442
- package/compliance/cache/3.1.0-beta.7/protocols/signals/index.yaml +0 -266
- package/compliance/cache/3.1.0-beta.7/protocols/sponsored-intelligence/index.yaml +0 -256
- package/compliance/cache/3.1.0-beta.7/specialisms/audience-sync/index.yaml +0 -313
- package/compliance/cache/3.1.0-beta.7/specialisms/brand-rights/index.yaml +0 -350
- package/compliance/cache/3.1.0-beta.7/specialisms/brand-rights/scenarios/governance_denied.yaml +0 -226
- package/compliance/cache/3.1.0-beta.7/specialisms/collection-lists/index.yaml +0 -359
- package/compliance/cache/3.1.0-beta.7/specialisms/content-standards/index.yaml +0 -572
- package/compliance/cache/3.1.0-beta.7/specialisms/creative-ad-server/index.yaml +0 -409
- package/compliance/cache/3.1.0-beta.7/specialisms/creative-generative/generative-seller.yaml +0 -807
- package/compliance/cache/3.1.0-beta.7/specialisms/creative-generative/index.yaml +0 -758
- package/compliance/cache/3.1.0-beta.7/specialisms/creative-template/index.yaml +0 -510
- package/compliance/cache/3.1.0-beta.7/specialisms/governance-aware-seller/index.yaml +0 -143
- package/compliance/cache/3.1.0-beta.7/specialisms/governance-aware-seller/scenarios/governance_multi_agent_rejected.yaml +0 -117
- package/compliance/cache/3.1.0-beta.7/specialisms/governance-delivery-monitor/index.yaml +0 -441
- package/compliance/cache/3.1.0-beta.7/specialisms/governance-spend-authority/denied.yaml +0 -221
- package/compliance/cache/3.1.0-beta.7/specialisms/governance-spend-authority/index.yaml +0 -330
- package/compliance/cache/3.1.0-beta.7/specialisms/property-lists/index.yaml +0 -482
- package/compliance/cache/3.1.0-beta.7/specialisms/sales-broadcast-tv/index.yaml +0 -738
- package/compliance/cache/3.1.0-beta.7/specialisms/sales-catalog-driven/index.yaml +0 -840
- package/compliance/cache/3.1.0-beta.7/specialisms/sales-guaranteed/index.yaml +0 -601
- package/compliance/cache/3.1.0-beta.7/specialisms/sales-non-guaranteed/index.yaml +0 -546
- package/compliance/cache/3.1.0-beta.7/specialisms/sales-proposal-mode/index.yaml +0 -586
- package/compliance/cache/3.1.0-beta.7/specialisms/sales-social/index.yaml +0 -919
- package/compliance/cache/3.1.0-beta.7/specialisms/signal-marketplace/index.yaml +0 -424
- package/compliance/cache/3.1.0-beta.7/specialisms/signal-marketplace/scenarios/governance_denied.yaml +0 -211
- package/compliance/cache/3.1.0-beta.7/specialisms/signal-owned/index.yaml +0 -317
- package/compliance/cache/3.1.0-beta.7/specialisms/sponsored-intelligence/index.yaml +0 -59
- package/compliance/cache/3.1.0-beta.7/test-kits/acme-outdoor-live.yaml +0 -78
- package/compliance/cache/3.1.0-beta.7/test-kits/acme-outdoor.yaml +0 -223
- package/compliance/cache/3.1.0-beta.7/test-kits/billing-gate-runner.yaml +0 -115
- package/compliance/cache/3.1.0-beta.7/test-kits/bistro-oranje.yaml +0 -126
- package/compliance/cache/3.1.0-beta.7/test-kits/distributed-brand-runner.yaml +0 -281
- package/compliance/cache/3.1.0-beta.7/test-kits/nova-motors.yaml +0 -262
- package/compliance/cache/3.1.0-beta.7/test-kits/osei-natural.yaml +0 -126
- package/compliance/cache/3.1.0-beta.7/test-kits/parallel-dispatch-runner.yaml +0 -196
- package/compliance/cache/3.1.0-beta.7/test-kits/rate-limit-trip-runner.yaml +0 -172
- package/compliance/cache/3.1.0-beta.7/test-kits/signed-requests-runner.yaml +0 -155
- package/compliance/cache/3.1.0-beta.7/test-kits/single-side-trust-runner.yaml +0 -294
- package/compliance/cache/3.1.0-beta.7/test-kits/substitution-observer-runner.yaml +0 -688
- package/compliance/cache/3.1.0-beta.7/test-kits/summit-foods.yaml +0 -125
- package/compliance/cache/3.1.0-beta.7/test-kits/webhook-receiver-runner.yaml +0 -265
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/001-minimal-plan.json +0 -43
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/002-full-plan.json +0 -217
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/003-bookkeeping-stripped.json +0 -60
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/004a-human-review-omitted.json +0 -43
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/004b-human-review-explicit-null.json +0 -49
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/005a-policy-categories-order-1.json +0 -53
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/005b-policy-categories-order-2.json +0 -57
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/006a-ext-trace-v1.json +0 -49
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/006b-ext-trace-v2.json +0 -53
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/007-unicode-objectives.json +0 -43
- package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/008-numeric-canonicalization.json +0 -65
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/README.md +0 -220
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/canonicalization.json +0 -241
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/keys.json +0 -60
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/001-no-signature-header.json +0 -24
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/002-wrong-tag.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/003-expired-signature.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/004-window-too-long.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/005-alg-not-allowed.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/006-missing-covered-component.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/007-missing-content-digest.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/008-unknown-keyid.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +0 -27
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/010-content-digest-mismatch.json +0 -33
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/011-malformed-header.json +0 -27
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/012-missing-expires-param.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/013-expires-le-created.json +0 -27
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/014-missing-nonce-param.json +0 -27
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/015-signature-invalid.json +0 -28
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/016-replayed-nonce.json +0 -35
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/017-key-revoked.json +0 -38
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +0 -28
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/019-signature-without-signature-input.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/020-rate-abuse.json +0 -34
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +0 -31
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/022-multi-valued-content-type.json +0 -31
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +0 -32
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/024-unquoted-string-param.json +0 -31
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +0 -43
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/026-non-ascii-host.json +0 -31
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +0 -25
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/028-unsigned-protocol-method-required.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/001-basic-post.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/002-post-with-content-digest.json +0 -31
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/003-es256-post.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/004-multiple-signature-labels.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/005-default-port-stripped.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/006-dot-segment-path.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/007-query-byte-preserved.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/008-percent-encoded-path.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/011-ipv6-authority.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +0 -30
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/README.md +0 -211
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/keys.json +0 -61
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/001-wrong-tag.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/002-expired-signature.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/003-window-too-long.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/005-missing-authority-component.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/006-missing-content-digest.json +0 -25
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/007-unknown-keyid.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/011-signature-without-input.json +0 -25
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/012-missing-expires-param.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/013-expires-le-created.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/015-signature-invalid.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/016-replayed-nonce.json +0 -37
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/017-key-revoked.json +0 -32
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/018-rate-abuse.json +0 -33
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/019-revocation-stale.json +0 -32
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +0 -41
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +0 -26
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/001-basic-post.json +0 -24
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/002-es256-post.json +0 -24
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +0 -24
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/004-default-port-stripped.json +0 -24
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +0 -24
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +0 -24
- package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +0 -25
- package/compliance/cache/3.1.0-beta.7/universal/billing-gate-dispatch.yaml +0 -450
- package/compliance/cache/3.1.0-beta.7/universal/canonical-format-validate-input.yaml +0 -640
- package/compliance/cache/3.1.0-beta.7/universal/capability-discovery.yaml +0 -125
- package/compliance/cache/3.1.0-beta.7/universal/collection-lists-pagination-integrity.yaml +0 -306
- package/compliance/cache/3.1.0-beta.7/universal/comply-controller-mode-gate.yaml +0 -141
- package/compliance/cache/3.1.0-beta.7/universal/content-standards-pagination-integrity.yaml +0 -326
- package/compliance/cache/3.1.0-beta.7/universal/deterministic-testing.yaml +0 -1430
- package/compliance/cache/3.1.0-beta.7/universal/error-compliance-signals.yaml +0 -377
- package/compliance/cache/3.1.0-beta.7/universal/error-compliance.yaml +0 -528
- package/compliance/cache/3.1.0-beta.7/universal/fictional-entities.yaml +0 -307
- package/compliance/cache/3.1.0-beta.7/universal/get-media-buys-pagination-integrity.yaml +0 -160
- package/compliance/cache/3.1.0-beta.7/universal/get-signals-pagination-integrity.yaml +0 -211
- package/compliance/cache/3.1.0-beta.7/universal/idempotency.yaml +0 -861
- package/compliance/cache/3.1.0-beta.7/universal/notification-config-event-scope.yaml +0 -119
- package/compliance/cache/3.1.0-beta.7/universal/notification-config-lifecycle.yaml +0 -337
- package/compliance/cache/3.1.0-beta.7/universal/notification-config-rejections.yaml +0 -107
- package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity-creative-formats.yaml +0 -265
- package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity-list-accounts.yaml +0 -245
- package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity.yaml +0 -263
- package/compliance/cache/3.1.0-beta.7/universal/property-lists-pagination-integrity.yaml +0 -307
- package/compliance/cache/3.1.0-beta.7/universal/read-tool-idempotency.yaml +0 -405
- package/compliance/cache/3.1.0-beta.7/universal/runner-output-contract.yaml +0 -1266
- package/compliance/cache/3.1.0-beta.7/universal/schema-validation-signals.yaml +0 -181
- package/compliance/cache/3.1.0-beta.7/universal/schema-validation.yaml +0 -548
- package/compliance/cache/3.1.0-beta.7/universal/security.yaml +0 -539
- package/compliance/cache/3.1.0-beta.7/universal/signed-requests.yaml +0 -217
- package/compliance/cache/3.1.0-beta.7/universal/stale-response-advisory.yaml +0 -295
- package/compliance/cache/3.1.0-beta.7/universal/storyboard-schema.yaml +0 -2136
- package/compliance/cache/3.1.0-beta.7/universal/v3-envelope-integrity.yaml +0 -117
- package/compliance/cache/3.1.0-beta.7/universal/version-negotiation.yaml +0 -130
- package/compliance/cache/3.1.0-beta.7/universal/webhook-emission.yaml +0 -411
- package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-bulk-webhooks.yaml +0 -82
- package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-product-webhooks.yaml +0 -83
- package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-products.yaml +0 -151
- package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-signal-webhooks.yaml +0 -83
- package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-signals.yaml +0 -149
- package/dist/lib/types/v3-1-beta/index.d.mts +0 -1
- package/dist/lib/types/v3-1-beta/index.d.ts +0 -1
- package/dist/lib/types/v3-1-beta/index.mjs +0 -1
- package/dist/lib/types/v3-1-beta/tools.generated.d.mts +0 -26788
- package/dist/lib/types/v3-1-beta/tools.generated.d.ts +0 -26788
- /package/dist/lib/{types/v3-1-beta/tools.generated.mjs → media-buy/action-types.mjs} +0 -0
|
@@ -18,16 +18,21 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var inline_exports = {};
|
|
20
20
|
__export(inline_exports, {
|
|
21
|
+
INLINE_REPORTING_AVAILABILITY_EVIDENCE_VERSION_V1: () => INLINE_REPORTING_AVAILABILITY_EVIDENCE_VERSION_V1,
|
|
21
22
|
InlineReportingSourceError: () => InlineReportingSourceError,
|
|
22
23
|
ReportingSourceNotReadyError: () => ReportingSourceNotReadyError,
|
|
23
|
-
createInlineReportingSourceExecutor: () => createInlineReportingSourceExecutor
|
|
24
|
+
createInlineReportingSourceExecutor: () => createInlineReportingSourceExecutor,
|
|
25
|
+
createInlineReportingSourceExecutorForTestsV1: () => createInlineReportingSourceExecutorForTestsV1,
|
|
26
|
+
inlineStagingCapacitiesForTestsV1: () => inlineStagingCapacitiesForTestsV1
|
|
24
27
|
});
|
|
25
28
|
module.exports = __toCommonJS(inline_exports);
|
|
26
29
|
var import_node_crypto = require("node:crypto");
|
|
30
|
+
var import_zod = require("zod");
|
|
27
31
|
var import_builder = require('./builder.js');
|
|
28
32
|
var import_conformance = require('./conformance.js');
|
|
29
33
|
var import_manifest = require('./manifest.js');
|
|
30
34
|
var import_source = require('./source.js');
|
|
35
|
+
const INLINE_REPORTING_AVAILABILITY_EVIDENCE_VERSION_V1 = "1.0";
|
|
31
36
|
class ReportingSourceNotReadyError extends Error {
|
|
32
37
|
constructor(message = "Reporting data is not ready") {
|
|
33
38
|
super(message);
|
|
@@ -50,7 +55,87 @@ const INLINE_MAX_OBJECT_BYTES_V1 = 64 * 1024 * 1024;
|
|
|
50
55
|
const INLINE_MAX_TOTAL_OBJECT_BYTES_V1 = 256 * 1024 * 1024;
|
|
51
56
|
const INLINE_MAX_SCOPE_OBJECT_BYTES_V1 = 32 * 1024 * 1024;
|
|
52
57
|
const INLINE_MAX_ROWS_V1 = 1e5;
|
|
53
|
-
|
|
58
|
+
const INLINE_SHIPPED_CAPACITIES_V1 = {
|
|
59
|
+
object: INLINE_MAX_OBJECT_BYTES_V1,
|
|
60
|
+
total: INLINE_MAX_TOTAL_OBJECT_BYTES_V1,
|
|
61
|
+
scope: INLINE_MAX_SCOPE_OBJECT_BYTES_V1,
|
|
62
|
+
executions: INLINE_MAX_EXECUTIONS_V1,
|
|
63
|
+
scopeExecutions: INLINE_MAX_EXECUTIONS_PER_SCOPE_V1
|
|
64
|
+
};
|
|
65
|
+
function tightenInlineStagingCapacities(override) {
|
|
66
|
+
const tighten = (shipped, value) => typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? Math.min(shipped, value) : shipped;
|
|
67
|
+
return {
|
|
68
|
+
object: tighten(INLINE_MAX_OBJECT_BYTES_V1, override.object),
|
|
69
|
+
total: tighten(INLINE_MAX_TOTAL_OBJECT_BYTES_V1, override.total),
|
|
70
|
+
scope: tighten(INLINE_MAX_SCOPE_OBJECT_BYTES_V1, override.scope),
|
|
71
|
+
executions: tighten(INLINE_MAX_EXECUTIONS_V1, override.executions),
|
|
72
|
+
scopeExecutions: tighten(INLINE_MAX_EXECUTIONS_PER_SCOPE_V1, override.scopeExecutions)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const INLINE_MAX_VALIDATION_WORK_UNITS_V1 = 5e6;
|
|
76
|
+
const INLINE_MAX_VALIDATION_SCAN_BYTES_V1 = INLINE_MAX_OBJECT_BYTES_V1;
|
|
77
|
+
const INLINE_MAX_VALIDATION_RETAINED_BYTES_V1 = INLINE_MAX_OBJECT_BYTES_V1;
|
|
78
|
+
const INLINE_RETAINED_BYTES_PER_ROW_V1 = 48;
|
|
79
|
+
const INLINE_RETAINED_BYTES_PER_CLAIM_V1 = 9;
|
|
80
|
+
const INLINE_MAX_STATUS_CHARS_V1 = 32;
|
|
81
|
+
const INLINE_NO_CLAIMS_OFFSET_V1 = -1;
|
|
82
|
+
const INLINE_MAX_EVIDENCE_OBJECT_KEYS_V1 = 16;
|
|
83
|
+
const INLINE_MAX_EVIDENCE_FIELD_CHARS_V1 = 1024;
|
|
84
|
+
const INLINE_EVIDENCE_ENVELOPE_KEYS_V1 = ["version", "cells"];
|
|
85
|
+
const INLINE_EVIDENCE_CELL_KEYS_V1 = ["constituent_id", "metric", "status", "reason", "data_through"];
|
|
86
|
+
const INLINE_UNAVAILABLE_ROW_STATUSES_V1 = [
|
|
87
|
+
"failed",
|
|
88
|
+
"reporting_delayed",
|
|
89
|
+
"not_ready",
|
|
90
|
+
"pending",
|
|
91
|
+
"unavailable",
|
|
92
|
+
"error"
|
|
93
|
+
];
|
|
94
|
+
const INLINE_UNAVAILABLE_CELL_STATUSES_V1 = ["unsupported", "delayed", "missing"];
|
|
95
|
+
const INLINE_MAX_PROTOTYPE_CHAIN_DEPTH_V1 = 64;
|
|
96
|
+
const INLINE_MAX_DECIMAL_EXPONENT_V1 = 400;
|
|
97
|
+
const InlineReportingMetricEvidenceV1Schema = import_zod.z.discriminatedUnion("status", [
|
|
98
|
+
import_zod.z.strictObject({
|
|
99
|
+
constituent_id: import_manifest.ReportingExternalIdV1Schema,
|
|
100
|
+
metric: import_source.ReportingMetricOrDimensionNameV1Schema,
|
|
101
|
+
status: import_zod.z.enum(["present", "explicit_zero"]),
|
|
102
|
+
data_through: import_zod.z.string().trim().min(1).max(64),
|
|
103
|
+
reason: import_zod.z.never().optional()
|
|
104
|
+
}),
|
|
105
|
+
import_zod.z.strictObject({
|
|
106
|
+
constituent_id: import_manifest.ReportingExternalIdV1Schema,
|
|
107
|
+
metric: import_source.ReportingMetricOrDimensionNameV1Schema,
|
|
108
|
+
status: import_zod.z.enum(["unsupported", "delayed", "partial", "stale", "missing"]),
|
|
109
|
+
reason: import_manifest.ReportingEvidenceReasonV1Schema,
|
|
110
|
+
data_through: import_zod.z.string().trim().min(1).max(64).optional()
|
|
111
|
+
})
|
|
112
|
+
]);
|
|
113
|
+
const InlineReportingAvailabilityEvidenceV1Schema = import_zod.z.strictObject({
|
|
114
|
+
version: import_zod.z.literal(INLINE_REPORTING_AVAILABILITY_EVIDENCE_VERSION_V1),
|
|
115
|
+
cells: import_zod.z.array(InlineReportingMetricEvidenceV1Schema).min(1).max(import_manifest.SOURCE_BATCH_MANIFEST_MAX_METRIC_AVAILABILITY_V1)
|
|
116
|
+
});
|
|
117
|
+
function createInlineReportingSourceExecutor(deliveryFetch, offeringInput, executorOptions = {}) {
|
|
118
|
+
return createInlineExecutorWithCapacities(
|
|
119
|
+
deliveryFetch,
|
|
120
|
+
offeringInput,
|
|
121
|
+
executorOptions,
|
|
122
|
+
INLINE_SHIPPED_CAPACITIES_V1
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
function createInlineReportingSourceExecutorForTestsV1(deliveryFetch, offeringInput, executorOptions, capacities, observer) {
|
|
126
|
+
return createInlineExecutorWithCapacities(
|
|
127
|
+
deliveryFetch,
|
|
128
|
+
offeringInput,
|
|
129
|
+
executorOptions,
|
|
130
|
+
tightenInlineStagingCapacities(capacities),
|
|
131
|
+
observer
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
function inlineStagingCapacitiesForTestsV1(capacities) {
|
|
135
|
+
return tightenInlineStagingCapacities(capacities);
|
|
136
|
+
}
|
|
137
|
+
function createInlineExecutorWithCapacities(deliveryFetch, offeringInput, executorOptions, capacities, observer) {
|
|
138
|
+
const evictSettled = executorOptions.replayRetention?.evictSettled === true;
|
|
54
139
|
const parsedOffering = import_source.ReportingSourceOfferingV1Schema.parse(offeringInput);
|
|
55
140
|
if (!parsedOffering.sourceExecution.manifestLevels.includes("basic")) {
|
|
56
141
|
throw new TypeError("Inline reporting requires a basic manifest offering");
|
|
@@ -143,17 +228,39 @@ function createInlineReportingSourceExecutor(deliveryFetch, offeringInput) {
|
|
|
143
228
|
if (existing.requestFingerprint !== requestFingerprint) {
|
|
144
229
|
return failure("INTEGRITY_FAILED", "terminal", "sourceExecutionKey was reused with a different request");
|
|
145
230
|
}
|
|
231
|
+
existing.reservation = void 0;
|
|
146
232
|
return awaitInlineExecution(existing, context.signal, request.deadline.deadlineAt);
|
|
147
233
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (
|
|
152
|
-
return failure(
|
|
234
|
+
const scopeCount = [...executions.values()].filter((candidate) => candidate.scopeKey === scopeKey).length;
|
|
235
|
+
const exhaustedGlobally = executions.size >= capacities.executions;
|
|
236
|
+
const exhaustedForScope = scopeCount >= capacities.scopeExecutions;
|
|
237
|
+
if ((exhaustedGlobally || exhaustedForScope) && !evictSettled) {
|
|
238
|
+
return failure(
|
|
239
|
+
"QUOTA_EXHAUSTED",
|
|
240
|
+
"terminal",
|
|
241
|
+
`Inline reporting ${exhaustedGlobally ? "replay" : "scope replay"} capacity is exhausted; supply a durable executor or an explicit replayRetention policy for long-lived feeds`
|
|
242
|
+
);
|
|
153
243
|
}
|
|
154
244
|
if (activeExecutions >= INLINE_MAX_CONCURRENT_EXECUTIONS_V1) {
|
|
155
245
|
return failure("RATE_LIMITED", "retryable", "Inline reporting concurrency capacity is exhausted");
|
|
156
246
|
}
|
|
247
|
+
const reclaimer = evictSettled ? createAdmissionReclaimer(executions, storage) : void 0;
|
|
248
|
+
if (exhaustedGlobally && reclaimer?.plan(scopeKey, false) === void 0) {
|
|
249
|
+
reclaimer?.release();
|
|
250
|
+
return failure(
|
|
251
|
+
"QUOTA_EXHAUSTED",
|
|
252
|
+
"terminal",
|
|
253
|
+
"Inline reporting replay capacity is exhausted; supply a durable executor or an explicit replayRetention policy for long-lived feeds"
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
if (scopeCount - (reclaimer?.plannedInScope(scopeKey) ?? 0) >= capacities.scopeExecutions && reclaimer?.plan(scopeKey, true) === void 0) {
|
|
257
|
+
reclaimer?.release();
|
|
258
|
+
return failure(
|
|
259
|
+
"QUOTA_EXHAUSTED",
|
|
260
|
+
"terminal",
|
|
261
|
+
"Inline reporting scope replay capacity is exhausted; supply a durable executor or an explicit replayRetention policy for long-lived feeds"
|
|
262
|
+
);
|
|
263
|
+
}
|
|
157
264
|
activeExecutions += 1;
|
|
158
265
|
const controller = new AbortController();
|
|
159
266
|
const pending = Promise.resolve().then(
|
|
@@ -167,7 +274,10 @@ function createInlineReportingSourceExecutor(deliveryFetch, offeringInput) {
|
|
|
167
274
|
controller.signal,
|
|
168
275
|
storage,
|
|
169
276
|
key,
|
|
170
|
-
scopeKey
|
|
277
|
+
scopeKey,
|
|
278
|
+
capacities,
|
|
279
|
+
reclaimer,
|
|
280
|
+
observer
|
|
171
281
|
)
|
|
172
282
|
).then((result) => ({ requestFingerprint, result })).catch(() => ({
|
|
173
283
|
requestFingerprint,
|
|
@@ -175,6 +285,7 @@ function createInlineReportingSourceExecutor(deliveryFetch, offeringInput) {
|
|
|
175
285
|
})).finally(() => {
|
|
176
286
|
activeExecutions -= 1;
|
|
177
287
|
entry.pending = false;
|
|
288
|
+
reclaimer?.release();
|
|
178
289
|
});
|
|
179
290
|
const entry = {
|
|
180
291
|
scopeKey,
|
|
@@ -206,13 +317,17 @@ function createInlineReportingSourceExecutor(deliveryFetch, offeringInput) {
|
|
|
206
317
|
};
|
|
207
318
|
return executor;
|
|
208
319
|
}
|
|
209
|
-
async function executeAndSeal(deliveryFetch, offering, format, request, deliveryDates, deadlineAt, signal, storage, executionNamespace, scopeKey) {
|
|
320
|
+
async function executeAndSeal(deliveryFetch, offering, format, request, deliveryDates, deadlineAt, signal, storage, executionNamespace, scopeKey, capacities, reclaimer, observer) {
|
|
210
321
|
let fetched;
|
|
211
322
|
try {
|
|
212
323
|
fetched = await deliveryFetch(
|
|
213
324
|
{
|
|
214
325
|
account: structuredClone(request.account),
|
|
215
326
|
media_buy_ids: [...request.coverage.mediaBuyIds],
|
|
327
|
+
constituents: request.coverage.constituents.map((constituent) => ({
|
|
328
|
+
constituent_id: constituent.constituentId,
|
|
329
|
+
media_buy_id: constituent.mediaBuyId
|
|
330
|
+
})),
|
|
216
331
|
start_date: deliveryDates.start,
|
|
217
332
|
end_date: deliveryDates.end,
|
|
218
333
|
source_read_cutoff_at: request.period.sourceReadCutoffAt,
|
|
@@ -246,70 +361,209 @@ async function executeAndSeal(deliveryFetch, offering, format, request, delivery
|
|
|
246
361
|
if (fetched === null) {
|
|
247
362
|
return failure("NOT_READY", "retryable", "Reporting data is not ready");
|
|
248
363
|
}
|
|
249
|
-
const
|
|
364
|
+
const fetchedRecord = !isRows(fetched) ? fetched : void 0;
|
|
365
|
+
let rawStatus;
|
|
366
|
+
try {
|
|
367
|
+
rawStatus = fetchedRecord?.status;
|
|
368
|
+
} catch {
|
|
369
|
+
return failure("SOURCE_PERMANENT", "terminal", "Inline delivery fetch returned an unreadable response");
|
|
370
|
+
}
|
|
371
|
+
if (rawStatus !== void 0 && typeof rawStatus !== "string") {
|
|
372
|
+
return failure("SOURCE_PERMANENT", "terminal", "Inline delivery fetch reported an unreadable status");
|
|
373
|
+
}
|
|
374
|
+
const responseStatus = boundedLowerCaseStatus(rawStatus);
|
|
250
375
|
if (["failed", "error", "canceled", "cancelled", "rejected"].includes(responseStatus ?? "")) {
|
|
251
376
|
return failure("SOURCE_TRANSIENT", "retryable", "Inline delivery fetch reported failure");
|
|
252
377
|
}
|
|
253
378
|
if (responseStatus === "unavailable") {
|
|
254
379
|
return failure("PARTIAL_RESULT", "retryable", "Inline delivery fetch reported unavailable data");
|
|
255
380
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
381
|
+
const readResponseField = createResponseFieldReader(fetchedRecord);
|
|
382
|
+
const scalarFailure = (() => {
|
|
383
|
+
try {
|
|
384
|
+
if (!isRows(fetched) && (["working", "submitted", "input_required", "deferred", "reporting_delayed", "not_ready", "pending"].includes(
|
|
385
|
+
responseStatus ?? ""
|
|
386
|
+
) || request.publicationClass === "AUTHORITATIVE" && readResponseField("is_final") === false)) {
|
|
387
|
+
return failure("NOT_READY", "retryable", "Reporting data is not ready");
|
|
388
|
+
}
|
|
389
|
+
if (request.publicationClass === "AUTHORITATIVE" && (isRows(fetched) || readResponseField("is_final") !== true && !["final", "adjusted"].includes(asStringOrUndefined(readResponseField("notification_type")) ?? ""))) {
|
|
390
|
+
return failure("NOT_READY", "retryable", "Authoritative inline reporting requires source finality evidence");
|
|
391
|
+
}
|
|
392
|
+
if (!isRows(fetched) && (Boolean(readResponseField("partial_data")) || looseCount(readResponseField("unavailable_count")) > 0 || looseCount(lengthOfUnknown(readResponseField("errors"))) > 0)) {
|
|
393
|
+
return failure("PARTIAL_RESULT", "retryable", "Inline delivery fetch returned partial data");
|
|
394
|
+
}
|
|
395
|
+
const pagination = readResponseField("pagination");
|
|
396
|
+
if (!isRows(fetched) && fetchedRecord !== void 0 && pagination !== void 0) {
|
|
397
|
+
const paginationRecord = asRowRecord(pagination);
|
|
398
|
+
if (paginationRecord?.has_more !== false || Boolean(paginationRecord?.next_cursor)) {
|
|
399
|
+
return failure("PARTIAL_RESULT", "retryable", "Inline delivery fetch returned unfinished pagination");
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return void 0;
|
|
403
|
+
} catch {
|
|
404
|
+
return failure("SOURCE_PERMANENT", "terminal", "Inline delivery fetch returned an unreadable response");
|
|
405
|
+
}
|
|
406
|
+
})();
|
|
407
|
+
if (scalarFailure) return scalarFailure;
|
|
408
|
+
let reportingRowsInput;
|
|
409
|
+
let mediaBuyDeliveriesInput;
|
|
410
|
+
try {
|
|
411
|
+
reportingRowsInput = fetchedRecord ? fetchedRecord.reporting_rows : void 0;
|
|
412
|
+
mediaBuyDeliveriesInput = fetchedRecord ? fetchedRecord.media_buy_deliveries : void 0;
|
|
413
|
+
} catch {
|
|
414
|
+
return failure("SOURCE_PERMANENT", "terminal", "Inline delivery fetch returned an invalid row collection");
|
|
263
415
|
}
|
|
264
|
-
|
|
265
|
-
|
|
416
|
+
const availabilityEvidenceSlot = fetchedRecord ? resolveOwnDataSlot(fetchedRecord, "availability_evidence") : { kind: "absent" };
|
|
417
|
+
if (reportingRowsInput !== void 0 && !Array.isArray(reportingRowsInput) || mediaBuyDeliveriesInput !== void 0 && !Array.isArray(mediaBuyDeliveriesInput)) {
|
|
418
|
+
return failure("SOURCE_PERMANENT", "terminal", "Inline delivery fetch returned an invalid row collection");
|
|
266
419
|
}
|
|
267
|
-
|
|
268
|
-
|
|
420
|
+
const reportingRows = reportingRowsInput;
|
|
421
|
+
const mediaBuyDeliveries = mediaBuyDeliveriesInput;
|
|
422
|
+
const reportingRowsLength = boundedCollectionLength(reportingRows);
|
|
423
|
+
const mediaBuyDeliveriesLength = boundedCollectionLength(mediaBuyDeliveries);
|
|
424
|
+
const sourceDeclaredLength = isRows(fetched) ? boundedCollectionLength(fetched) : reportingRows !== void 0 ? reportingRowsLength : mediaBuyDeliveriesLength;
|
|
425
|
+
if (reportingRowsLength === void 0 || mediaBuyDeliveriesLength === void 0 || sourceDeclaredLength === void 0) {
|
|
426
|
+
return failure("SOURCE_PERMANENT", "terminal", "Inline delivery fetch returned an invalid row collection");
|
|
269
427
|
}
|
|
270
|
-
if (!isRows(fetched) &&
|
|
428
|
+
if (!isRows(fetched) && reportingRows === void 0 && mediaBuyDeliveries === void 0) {
|
|
271
429
|
return failure("SOURCE_PERMANENT", "terminal", "Inline delivery fetch omitted its row collection");
|
|
272
430
|
}
|
|
273
|
-
|
|
431
|
+
let responsePeriod;
|
|
432
|
+
let responseCurrency;
|
|
433
|
+
try {
|
|
434
|
+
const period = asRowRecord(readResponseField("reporting_period"));
|
|
435
|
+
const periodStart = period?.start;
|
|
436
|
+
const periodEnd = period?.end;
|
|
437
|
+
responsePeriod = {
|
|
438
|
+
present: period !== void 0 && periodStart !== void 0 && periodEnd !== void 0,
|
|
439
|
+
start: periodStart,
|
|
440
|
+
end: periodEnd
|
|
441
|
+
};
|
|
442
|
+
responseCurrency = readResponseField("currency");
|
|
443
|
+
} catch {
|
|
444
|
+
return failure("SOURCE_PERMANENT", "terminal", "Inline delivery fetch returned an unreadable response");
|
|
445
|
+
}
|
|
446
|
+
if (!isRows(fetched) && (!responsePeriod.present || !deliveryPeriodBoundaryMatches(responsePeriod.start, deliveryDates.start, request.period.start) || !deliveryPeriodBoundaryMatches(responsePeriod.end, deliveryDates.end, request.period.end))) {
|
|
274
447
|
return failure("PARTIAL_RESULT", "retryable", "Inline delivery fetch did not prove the requested half-open period");
|
|
275
448
|
}
|
|
276
|
-
if (!isRows(fetched) &&
|
|
449
|
+
if (!isRows(fetched) && responseCurrency !== void 0 && responseCurrency !== request.sourceSettings.currency) {
|
|
277
450
|
return failure(
|
|
278
451
|
"INTEGRITY_FAILED",
|
|
279
452
|
"terminal",
|
|
280
453
|
"Inline delivery currency does not match the frozen source settings"
|
|
281
454
|
);
|
|
282
455
|
}
|
|
283
|
-
if (!isRows(fetched) && (
|
|
456
|
+
if (!isRows(fetched) && (reportingRowsLength > INLINE_MAX_ROWS_V1 || mediaBuyDeliveriesLength > INLINE_MAX_ROWS_V1 || reportingRowsLength + mediaBuyDeliveriesLength > INLINE_MAX_ROWS_V1)) {
|
|
284
457
|
return failure("QUOTA_EXHAUSTED", "terminal", "Inline delivery fetch exceeded the row limit");
|
|
285
458
|
}
|
|
286
|
-
if (!isRows(fetched) &&
|
|
459
|
+
if (!isRows(fetched) && reportingRows !== void 0 && mediaBuyDeliveries !== void 0 && reportingRowsLength === 0 !== (mediaBuyDeliveriesLength === 0)) {
|
|
287
460
|
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery row collections disagree about zero delivery");
|
|
288
461
|
}
|
|
289
|
-
const
|
|
290
|
-
|
|
462
|
+
const sourceCollection = isRows(fetched) ? fetched : reportingRows ?? mediaBuyDeliveries ?? [];
|
|
463
|
+
const auxiliaryDeclaredLength = !isRows(fetched) && reportingRows !== void 0 ? mediaBuyDeliveriesLength : 0;
|
|
464
|
+
if (sourceDeclaredLength > INLINE_MAX_ROWS_V1 || auxiliaryDeclaredLength > INLINE_MAX_ROWS_V1) {
|
|
291
465
|
return failure("QUOTA_EXHAUSTED", "terminal", "Inline delivery fetch exceeded the row limit");
|
|
292
466
|
}
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
467
|
+
const sourceRowInputs = captureRowCollection(sourceCollection, sourceDeclaredLength);
|
|
468
|
+
const auxiliaryRowInputs = auxiliaryDeclaredLength > 0 ? captureRowCollection(mediaBuyDeliveries ?? [], auxiliaryDeclaredLength) : [];
|
|
469
|
+
let availabilityEvidence;
|
|
470
|
+
if (!isRows(fetched) && availabilityEvidenceSlot.kind === "unreadable") {
|
|
471
|
+
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery availability evidence is invalid");
|
|
296
472
|
}
|
|
297
|
-
if (
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
473
|
+
if (!isRows(fetched) && availabilityEvidenceSlot.kind === "data") {
|
|
474
|
+
try {
|
|
475
|
+
availabilityEvidence = parseInlineAvailabilityEvidence(
|
|
476
|
+
availabilityEvidenceSlot.value,
|
|
477
|
+
request
|
|
478
|
+
);
|
|
479
|
+
} catch {
|
|
480
|
+
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery availability evidence is invalid");
|
|
303
481
|
}
|
|
304
|
-
|
|
482
|
+
}
|
|
483
|
+
const captureLayout = captureLayoutFor(request);
|
|
484
|
+
const claimBearingRowCount = sourceRowInputs.length + (availabilityEvidenceSlot.kind === "data" ? auxiliaryRowInputs.length : 0);
|
|
485
|
+
if (workUnitsExceedCap(
|
|
486
|
+
claimBearingRowCount,
|
|
487
|
+
1 + request.requestedMetrics.length + request.requestedDimensions.length,
|
|
488
|
+
INLINE_MAX_VALIDATION_WORK_UNITS_V1
|
|
489
|
+
) || workUnitsExceedCap(
|
|
490
|
+
claimBearingRowCount,
|
|
491
|
+
INLINE_RETAINED_BYTES_PER_ROW_V1 + captureLayout.fields.length * INLINE_RETAINED_BYTES_PER_CLAIM_V1,
|
|
492
|
+
INLINE_MAX_VALIDATION_RETAINED_BYTES_V1
|
|
493
|
+
)) {
|
|
494
|
+
return failure("QUOTA_EXHAUSTED", "terminal", "Inline availability verification exceeded the work budget");
|
|
495
|
+
}
|
|
496
|
+
const strictClaims = availabilityEvidence !== void 0;
|
|
497
|
+
let scanBudget = INLINE_MAX_VALIDATION_SCAN_BYTES_V1;
|
|
498
|
+
const chargeScan = (units) => {
|
|
499
|
+
if (units > scanBudget) throw new InlineWorkBudgetExhaustedError();
|
|
500
|
+
scanBudget -= units;
|
|
501
|
+
};
|
|
502
|
+
const sourceReserved = [];
|
|
503
|
+
const auxiliaryReserved = [];
|
|
504
|
+
for (const [rows2, captured] of [
|
|
505
|
+
[sourceRowInputs, sourceReserved],
|
|
506
|
+
[auxiliaryRowInputs, auxiliaryReserved]
|
|
507
|
+
]) {
|
|
508
|
+
for (const row of rows2) {
|
|
509
|
+
const reserved = beginRowReserved(row);
|
|
510
|
+
captured.push(reserved);
|
|
511
|
+
if (reserved !== void 0 && (rowStatusIsUnavailable(reserved) || rowDeclaresPartialData(reserved))) {
|
|
512
|
+
return failure("PARTIAL_RESULT", "retryable", "Inline delivery fetch returned an unavailable row");
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
for (const reserved of [...sourceReserved, ...auxiliaryReserved]) {
|
|
517
|
+
if (reserved === void 0) continue;
|
|
518
|
+
readRowCurrency(reserved);
|
|
519
|
+
if (typeof reserved.currency === "string" && reserved.currency !== request.sourceSettings.currency) {
|
|
305
520
|
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery row currency does not match source settings");
|
|
306
521
|
}
|
|
522
|
+
}
|
|
523
|
+
let sourceSnapshots;
|
|
524
|
+
let auxiliarySnapshots;
|
|
525
|
+
try {
|
|
526
|
+
const claimRowCount = sourceReserved.length + (strictClaims ? auxiliaryReserved.length : 0);
|
|
527
|
+
const store = createClaimStore(captureLayout, claimRowCount);
|
|
528
|
+
sourceSnapshots = sourceReserved.map(
|
|
529
|
+
(reserved, index) => captureRowSnapshot(reserved, store, index, strictClaims, chargeScan)
|
|
530
|
+
);
|
|
531
|
+
auxiliarySnapshots = auxiliaryReserved.map(
|
|
532
|
+
(reserved, index) => strictClaims ? captureRowSnapshot(reserved, store, sourceReserved.length + index, strictClaims, chargeScan) : captureRowIdentityOnly(reserved, store)
|
|
533
|
+
);
|
|
534
|
+
} catch (error) {
|
|
535
|
+
if (error instanceof InlineWorkBudgetExhaustedError) {
|
|
536
|
+
return failure("QUOTA_EXHAUSTED", "terminal", "Inline availability verification exceeded the scan budget");
|
|
537
|
+
}
|
|
538
|
+
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery row contains invalid evidence values");
|
|
539
|
+
}
|
|
540
|
+
const allSnapshots = [...sourceSnapshots, ...auxiliarySnapshots];
|
|
541
|
+
if (validationWorkExceedsCap(
|
|
542
|
+
sourceSnapshots,
|
|
543
|
+
auxiliarySnapshots,
|
|
544
|
+
request,
|
|
545
|
+
availabilityEvidence !== void 0,
|
|
546
|
+
INLINE_MAX_VALIDATION_WORK_UNITS_V1
|
|
547
|
+
)) {
|
|
548
|
+
return failure("QUOTA_EXHAUSTED", "terminal", "Inline availability verification exceeded the work budget");
|
|
549
|
+
}
|
|
550
|
+
const admittedMediaBuyIds = new Set(
|
|
551
|
+
request.coverage.constituents.flatMap((constituent) => constituent.mediaBuyId ? [constituent.mediaBuyId] : [])
|
|
552
|
+
);
|
|
553
|
+
const sourceSnapshotsByMediaBuyId = groupSnapshotsByMediaBuyId(sourceSnapshots, admittedMediaBuyIds);
|
|
554
|
+
const auxiliarySnapshotsByMediaBuyId = groupSnapshotsByMediaBuyId(auxiliarySnapshots, admittedMediaBuyIds);
|
|
555
|
+
if (sourceSnapshots.length > 0) {
|
|
556
|
+
if (allSnapshots.some((snapshot) => !admittedMediaBuyIds.has(snapshot?.mediaBuyId ?? ""))) {
|
|
557
|
+
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery fetch returned an out-of-scope row");
|
|
558
|
+
}
|
|
307
559
|
if (request.coverage.constituents.some((constituent) => {
|
|
308
560
|
if (constituent.constituentKind !== "media_buy" || !constituent.mediaBuyId) return true;
|
|
309
|
-
const constituentRows =
|
|
310
|
-
return constituentRows.
|
|
311
|
-
(
|
|
312
|
-
)
|
|
561
|
+
const constituentRows = sourceSnapshotsByMediaBuyId.get(constituent.mediaBuyId) ?? NO_SNAPSHOTS;
|
|
562
|
+
return constituentRows.some(
|
|
563
|
+
(snapshot) => request.requestedDimensions.some((dimension) => !snapshotHasDimension(snapshot, dimension))
|
|
564
|
+
) || availabilityEvidence === void 0 && (constituentRows.length === 0 || constituentRows.some(
|
|
565
|
+
(snapshot) => request.requestedMetrics.some((metric) => snapshotFieldValue(snapshot, metric) === void 0)
|
|
566
|
+
));
|
|
313
567
|
})) {
|
|
314
568
|
return failure(
|
|
315
569
|
"PARTIAL_RESULT",
|
|
@@ -318,37 +572,35 @@ async function executeAndSeal(deliveryFetch, offering, format, request, delivery
|
|
|
318
572
|
);
|
|
319
573
|
}
|
|
320
574
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
let rows;
|
|
328
|
-
try {
|
|
329
|
-
rows = sourceRows.map(
|
|
330
|
-
(row) => projectEvidenceRow(row, request, (upperBound) => {
|
|
331
|
-
if (upperBound > projectionBudget) throw new RangeError("Inline projection capacity exhausted");
|
|
332
|
-
projectionBudget -= upperBound;
|
|
333
|
-
})
|
|
575
|
+
if (availabilityEvidence !== void 0) {
|
|
576
|
+
const rowEvidenceFailure = validateSnapshotsAgainstAvailabilityEvidence(
|
|
577
|
+
sourceSnapshotsByMediaBuyId,
|
|
578
|
+
auxiliarySnapshotsByMediaBuyId,
|
|
579
|
+
request,
|
|
580
|
+
availabilityEvidence.cells
|
|
334
581
|
);
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
582
|
+
if (rowEvidenceFailure === "partial") {
|
|
583
|
+
return failure("PARTIAL_RESULT", "retryable", "Inline delivery rows do not prove every metric marked present");
|
|
584
|
+
}
|
|
585
|
+
if (rowEvidenceFailure === "integrity") {
|
|
586
|
+
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery rows contradict availability evidence");
|
|
338
587
|
}
|
|
339
|
-
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery row contains invalid evidence values");
|
|
340
588
|
}
|
|
341
589
|
const readsPartialPeriod = Date.parse(request.period.sourceReadCutoffAt) < Date.parse(request.period.end);
|
|
342
|
-
if (readsPartialPeriod && (isRows(fetched) ||
|
|
590
|
+
if (readsPartialPeriod && (isRows(fetched) || readResponseField("data_through") === void 0 || readResponseField("observed_at") === void 0)) {
|
|
343
591
|
return failure(
|
|
344
592
|
"PARTIAL_RESULT",
|
|
345
593
|
"retryable",
|
|
346
594
|
"Inline delivery fetch did not provide temporal evidence for the source read cutoff"
|
|
347
595
|
);
|
|
348
596
|
}
|
|
349
|
-
const observedAt = isRows(fetched) ? request.period.sourceReadCutoffAt : normalizeDeliveryInstant(
|
|
597
|
+
const observedAt = isRows(fetched) ? request.period.sourceReadCutoffAt : normalizeDeliveryInstant(
|
|
598
|
+
readResponseField("observed_at") ?? request.period.sourceReadCutoffAt,
|
|
599
|
+
deliveryDates,
|
|
600
|
+
request.period
|
|
601
|
+
);
|
|
350
602
|
const defaultDataThrough = request.publicationClass === "AUTHORITATIVE" ? request.period.end : Date.parse(request.period.sourceReadCutoffAt) < Date.parse(request.period.end) ? request.period.sourceReadCutoffAt : request.period.end;
|
|
351
|
-
const dataThrough = isRows(fetched) ? defaultDataThrough : normalizeDeliveryInstant(
|
|
603
|
+
const dataThrough = isRows(fetched) ? defaultDataThrough : normalizeDeliveryInstant(readResponseField("data_through") ?? defaultDataThrough, deliveryDates, request.period);
|
|
352
604
|
const acquiredAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
353
605
|
const startMs = Date.parse(request.period.start);
|
|
354
606
|
const endMs = Date.parse(request.period.end);
|
|
@@ -359,15 +611,110 @@ async function executeAndSeal(deliveryFetch, offering, format, request, delivery
|
|
|
359
611
|
if (request.publicationClass === "AUTHORITATIVE" && dataThroughMs < endMs) {
|
|
360
612
|
return failure("NOT_READY", "retryable", "Authoritative inline reporting has not reached period end");
|
|
361
613
|
}
|
|
362
|
-
if (![dataThroughMs, observedMs].every(Number.isFinite) || dataThroughMs < startMs || dataThroughMs > endMs || dataThroughMs > cutoffMs || dataThroughMs > observedMs || observedMs > acquiredMs ||
|
|
614
|
+
if (![dataThroughMs, observedMs].every(Number.isFinite) || dataThroughMs < startMs || dataThroughMs > endMs || dataThroughMs > cutoffMs || dataThroughMs > observedMs || observedMs > acquiredMs || sourceSnapshots.length > 0 && dataThroughMs <= startMs) {
|
|
363
615
|
return failure("SOURCE_PERMANENT", "terminal", "Inline delivery fetch returned invalid temporal evidence");
|
|
364
616
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
617
|
+
const declaredMetrics = new Map(offering.metrics.map((metric) => [metric.name, metric]));
|
|
618
|
+
const constituentIdsWithRows = new Set(
|
|
619
|
+
request.coverage.constituents.filter((constituent) => constituent.mediaBuyId && sourceSnapshotsByMediaBuyId.has(constituent.mediaBuyId)).map((constituent) => constituent.constituentId)
|
|
620
|
+
);
|
|
621
|
+
let projectedAvailability;
|
|
622
|
+
if (availabilityEvidence) {
|
|
623
|
+
try {
|
|
624
|
+
projectedAvailability = projectInlineAvailabilityEvidence(
|
|
625
|
+
availabilityEvidence.cells,
|
|
626
|
+
request,
|
|
627
|
+
declaredMetrics,
|
|
628
|
+
deliveryDates,
|
|
629
|
+
dataThrough,
|
|
630
|
+
sourceSnapshots.length,
|
|
631
|
+
constituentIdsWithRows
|
|
632
|
+
);
|
|
633
|
+
} catch {
|
|
634
|
+
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery availability evidence is contradictory");
|
|
635
|
+
}
|
|
636
|
+
} else {
|
|
637
|
+
projectedAvailability = projectLegacyAvailability(request, declaredMetrics, dataThrough, sourceSnapshots.length);
|
|
638
|
+
}
|
|
639
|
+
if (request.coverage.expected === "full" && projectedAvailability.coverageStatus !== "full") {
|
|
640
|
+
return failure("PARTIAL_RESULT", "retryable", "Inline delivery evidence does not satisfy full requested coverage");
|
|
641
|
+
}
|
|
642
|
+
if (request.publicationClass === "AUTHORITATIVE" && projectedAvailability.metricAvailability.some(
|
|
643
|
+
(cell) => !["present", "explicit_zero"].includes(cell.status) || Date.parse(cell.dataThrough ?? "") !== endMs
|
|
644
|
+
)) {
|
|
645
|
+
return failure("PARTIAL_RESULT", "retryable", "Authoritative inline reporting has incomplete metric evidence");
|
|
646
|
+
}
|
|
647
|
+
const reservedBytes = reclaimer?.grantReservedBytes(scopeKey) ?? { global: 0, scope: 0 };
|
|
648
|
+
let plannedGlobalCredit = reservedBytes.global;
|
|
649
|
+
let plannedScopeCredit = reservedBytes.scope;
|
|
650
|
+
const globalRoom = () => capacities.total - storage.totalBytes + plannedGlobalCredit;
|
|
651
|
+
const scopeRoom = () => capacities.scope - (storage.scopeBytes.get(scopeKey) ?? 0) + plannedScopeCredit;
|
|
652
|
+
const capacity = () => Math.min(capacities.object, globalRoom(), scopeRoom());
|
|
653
|
+
const planMoreCapacity = () => {
|
|
654
|
+
for (; ; ) {
|
|
655
|
+
const freed = reclaimer?.plan(scopeKey, scopeRoom() <= globalRoom(), true);
|
|
656
|
+
if (freed === void 0) return false;
|
|
657
|
+
if (freed.bytes <= 0) continue;
|
|
658
|
+
plannedGlobalCredit += freed.bytes;
|
|
659
|
+
if (freed.sameScope) plannedScopeCredit += freed.bytes;
|
|
660
|
+
return true;
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
const growCapacity = (available) => {
|
|
664
|
+
observer?.onCapacityRequest?.();
|
|
665
|
+
if (!planMoreCapacity()) return void 0;
|
|
666
|
+
const grown = capacity();
|
|
667
|
+
return grown > available ? grown : void 0;
|
|
668
|
+
};
|
|
669
|
+
let remainingCapacity = capacity();
|
|
670
|
+
let projectionBudget = remainingCapacity;
|
|
671
|
+
let rows;
|
|
672
|
+
while (rows === void 0) {
|
|
673
|
+
projectionBudget = remainingCapacity;
|
|
674
|
+
try {
|
|
675
|
+
rows = sourceSnapshots.map(
|
|
676
|
+
(snapshot) => projectSnapshotRow(
|
|
677
|
+
snapshot,
|
|
678
|
+
request,
|
|
679
|
+
(upperBound) => {
|
|
680
|
+
if (upperBound > projectionBudget) throw new RangeError("Inline projection capacity exhausted");
|
|
681
|
+
projectionBudget -= upperBound;
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
allowMissingMetrics: true,
|
|
685
|
+
allowMissingDimensions: true,
|
|
686
|
+
strictMetricClaims: availabilityEvidence !== void 0,
|
|
687
|
+
includeDimensions: true
|
|
688
|
+
}
|
|
689
|
+
)
|
|
690
|
+
);
|
|
691
|
+
} catch (error) {
|
|
692
|
+
if (!(error instanceof RangeError)) {
|
|
693
|
+
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery row contains invalid evidence values");
|
|
694
|
+
}
|
|
695
|
+
const grown = growCapacity(remainingCapacity);
|
|
696
|
+
if (grown === void 0) {
|
|
697
|
+
return failure("STAGING_FAILED", "terminal", "Inline delivery evidence exceeds the bounded replay capacity");
|
|
698
|
+
}
|
|
699
|
+
remainingCapacity = grown;
|
|
700
|
+
}
|
|
370
701
|
}
|
|
702
|
+
let encoded;
|
|
703
|
+
while (encoded === void 0) {
|
|
704
|
+
try {
|
|
705
|
+
encoded = encodeRows(rows, format.mediaType, remainingCapacity);
|
|
706
|
+
} catch (error) {
|
|
707
|
+
if (!(error instanceof RangeError)) {
|
|
708
|
+
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery row contains invalid evidence values");
|
|
709
|
+
}
|
|
710
|
+
const grown = growCapacity(remainingCapacity);
|
|
711
|
+
if (grown === void 0) {
|
|
712
|
+
return failure("STAGING_FAILED", "terminal", "Inline delivery evidence exceeds the bounded replay capacity");
|
|
713
|
+
}
|
|
714
|
+
remainingCapacity = grown;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
const bytes = encoded;
|
|
371
718
|
const objectDigest = digest(bytes);
|
|
372
719
|
const objectRef = `inline-${executionNamespace.slice(0, 32)}`;
|
|
373
720
|
const generation = `sha256-${objectDigest}`;
|
|
@@ -381,25 +728,423 @@ async function executeAndSeal(deliveryFetch, offering, format, request, delivery
|
|
|
381
728
|
byteCount: bytes.byteLength,
|
|
382
729
|
rowCount: rows.length
|
|
383
730
|
};
|
|
384
|
-
|
|
731
|
+
let built;
|
|
732
|
+
try {
|
|
733
|
+
built = (0, import_builder.buildReportingSourceManifestV1)({
|
|
734
|
+
level: "basic",
|
|
735
|
+
request,
|
|
736
|
+
stagedCommitRef: `inline-manifest-${executionNamespace.slice(0, 32)}`,
|
|
737
|
+
objects: [object],
|
|
738
|
+
completeness: {
|
|
739
|
+
terminal: true,
|
|
740
|
+
rowsComplete: true,
|
|
741
|
+
requestedGroupsComplete: true
|
|
742
|
+
},
|
|
743
|
+
controlTotals: [],
|
|
744
|
+
metricAvailability: projectedAvailability.metricAvailability,
|
|
745
|
+
coverage: {
|
|
746
|
+
status: projectedAvailability.coverageStatus,
|
|
747
|
+
constituents: projectedAvailability.coverageConstituents
|
|
748
|
+
},
|
|
749
|
+
observedAt,
|
|
750
|
+
dataThrough,
|
|
751
|
+
finalityEvidence: {
|
|
752
|
+
owner: "adapter",
|
|
753
|
+
basis: request.publicationClass === "PROVISIONAL_SNAPSHOT" ? "provisional_observation" : "source_declared",
|
|
754
|
+
observedAt,
|
|
755
|
+
...request.publicationClass === "AUTHORITATIVE" ? { evidenceRef: "get_media_buy_delivery.is_final" } : {}
|
|
756
|
+
},
|
|
757
|
+
explicitZero: projectedAvailability.explicitZero,
|
|
758
|
+
acquiredAt,
|
|
759
|
+
...rows.length === 0 ? {} : { eventTimeRange: { start: request.period.start, end: dataThrough } },
|
|
760
|
+
warnings: []
|
|
761
|
+
});
|
|
762
|
+
} catch (error) {
|
|
763
|
+
if (!availabilityEvidence) throw error;
|
|
764
|
+
if (error instanceof import_manifest.SourceBatchContractError && error.code === "SOURCE_MANIFEST_TOO_LARGE") {
|
|
765
|
+
return failure("QUOTA_EXHAUSTED", "terminal", "Inline reporting manifest exceeded the bounded size limit");
|
|
766
|
+
}
|
|
767
|
+
return failure("INTEGRITY_FAILED", "terminal", "Inline delivery availability evidence is contradictory");
|
|
768
|
+
}
|
|
769
|
+
if (Date.parse(deadlineAt) <= Date.now()) {
|
|
770
|
+
return failure("DEADLINE_EXCEEDED", "retryable", "Inline reporting execution deadline elapsed");
|
|
771
|
+
}
|
|
772
|
+
if (reclaimer !== void 0 && !reclaimer.commit(scopeKey)) {
|
|
773
|
+
return failure(
|
|
774
|
+
"STAGING_FAILED",
|
|
775
|
+
"terminal",
|
|
776
|
+
"Inline reporting could not reacquire the capacity a revoked reservation had promised"
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
storage.objects.set(objectRef, { request: structuredClone(request), generation, bytes: Uint8Array.from(bytes) });
|
|
780
|
+
storage.totalBytes += bytes.byteLength;
|
|
781
|
+
storage.scopeBytes.set(scopeKey, (storage.scopeBytes.get(scopeKey) ?? 0) + bytes.byteLength);
|
|
782
|
+
return {
|
|
783
|
+
ok: true,
|
|
784
|
+
response: (0, import_source.completedReportingSourceResponseV1)({ request, manifest: built.reference }),
|
|
785
|
+
manifestBytes: built.manifestBytes
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
function parseInlineAvailabilityEvidence(input, request) {
|
|
789
|
+
if (typeof input !== "object" || input === null) throw new TypeError("Availability evidence is not an envelope");
|
|
790
|
+
const envelope = snapshotOwnDataObject(input, INLINE_EVIDENCE_ENVELOPE_KEYS_V1);
|
|
791
|
+
const inputCells = envelope.cells;
|
|
792
|
+
const cellCount = Array.isArray(inputCells) ? boundedCollectionLength(inputCells) : void 0;
|
|
793
|
+
if (cellCount === void 0) throw new TypeError("Availability evidence cells are not a bounded array");
|
|
794
|
+
if (cellCount > import_manifest.SOURCE_BATCH_MANIFEST_MAX_METRIC_AVAILABILITY_V1) {
|
|
795
|
+
throw new TypeError("Availability evidence exceeds the cell limit");
|
|
796
|
+
}
|
|
797
|
+
const cellSnapshot = new Array(cellCount);
|
|
798
|
+
for (let index = 0; index < cellCount; index += 1) {
|
|
799
|
+
const cell = inputCells[index];
|
|
800
|
+
if (typeof cell !== "object" || cell === null || Array.isArray(cell)) {
|
|
801
|
+
throw new TypeError("Availability evidence cell is not an object");
|
|
802
|
+
}
|
|
803
|
+
cellSnapshot[index] = snapshotOwnDataObject(cell, INLINE_EVIDENCE_CELL_KEYS_V1);
|
|
804
|
+
}
|
|
805
|
+
const parsed = InlineReportingAvailabilityEvidenceV1Schema.parse({ ...envelope, cells: cellSnapshot });
|
|
806
|
+
const expected = new Set(
|
|
807
|
+
request.coverage.constituents.flatMap(
|
|
808
|
+
(constituent) => request.requestedMetrics.map((metric) => availabilityCellKey(constituent.constituentId, metric))
|
|
809
|
+
)
|
|
810
|
+
);
|
|
811
|
+
const seen = /* @__PURE__ */ new Set();
|
|
812
|
+
for (const cell of parsed.cells) {
|
|
813
|
+
const key = availabilityCellKey(cell.constituent_id, cell.metric);
|
|
814
|
+
if (!expected.has(key) || seen.has(key)) throw new TypeError("Availability cell is duplicate or out of scope");
|
|
815
|
+
seen.add(key);
|
|
816
|
+
}
|
|
817
|
+
if (seen.size !== expected.size) throw new TypeError("Availability evidence must cover the requested matrix");
|
|
818
|
+
const cellsByKey = new Map(parsed.cells.map((cell) => [availabilityCellKey(cell.constituent_id, cell.metric), cell]));
|
|
819
|
+
return {
|
|
820
|
+
...parsed,
|
|
821
|
+
cells: request.coverage.constituents.flatMap(
|
|
822
|
+
(constituent) => request.requestedMetrics.map((metric) => {
|
|
823
|
+
const cell = cellsByKey.get(availabilityCellKey(constituent.constituentId, metric));
|
|
824
|
+
if (!cell) throw new TypeError("Availability evidence must cover the requested matrix");
|
|
825
|
+
return cell;
|
|
826
|
+
})
|
|
827
|
+
)
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
const NO_SNAPSHOTS = [];
|
|
831
|
+
class InlineWorkBudgetExhaustedError extends Error {
|
|
832
|
+
}
|
|
833
|
+
const UNCLAIMED_V1 = { claimed: false };
|
|
834
|
+
function captureLayoutFor(request) {
|
|
835
|
+
const fields = [];
|
|
836
|
+
const indexOf = /* @__PURE__ */ new Map();
|
|
837
|
+
const reservedFields = /* @__PURE__ */ new Set();
|
|
838
|
+
const requestedAsMetric = new Set(request.requestedMetrics);
|
|
839
|
+
for (const field of [...request.requestedMetrics, ...request.requestedDimensions]) {
|
|
840
|
+
if (indexOf.has(field)) continue;
|
|
841
|
+
if (field === "media_buy_id" && !requestedAsMetric.has(field)) continue;
|
|
842
|
+
indexOf.set(field, fields.length);
|
|
843
|
+
fields.push(field);
|
|
844
|
+
if (INLINE_RESERVED_ROW_FIELDS_V1.includes(field)) reservedFields.add(field);
|
|
845
|
+
}
|
|
846
|
+
return { fields, indexOf, reservedFields };
|
|
847
|
+
}
|
|
848
|
+
const CLAIM_DIRECT_CLAIMED_V1 = 1 << 0;
|
|
849
|
+
const CLAIM_NESTED_CLAIMED_V1 = 1 << 1;
|
|
850
|
+
const CLAIM_DIRECT_VALID_V1 = 1 << 2;
|
|
851
|
+
const CLAIM_NESTED_VALID_V1 = 1 << 3;
|
|
852
|
+
const CLAIM_VALUE_IS_ZERO_V1 = 1 << 4;
|
|
853
|
+
const CLAIM_CLAIM_IS_ZERO_V1 = 1 << 5;
|
|
854
|
+
const CLAIM_DISAGREE_V1 = 1 << 6;
|
|
855
|
+
const INLINE_RESERVED_ROW_FIELDS_V1 = ["media_buy_id", "currency", "status", "partial_data", "totals"];
|
|
856
|
+
function beginRowReserved(row) {
|
|
857
|
+
const record = asRowRecord(row);
|
|
858
|
+
if (!record) return void 0;
|
|
859
|
+
return { record, status: ownDataValue(record, "status") };
|
|
860
|
+
}
|
|
861
|
+
function rowStatusIsUnavailable(reserved) {
|
|
862
|
+
const status = boundedLowerCaseStatus(reserved.status);
|
|
863
|
+
return status !== void 0 && INLINE_UNAVAILABLE_ROW_STATUSES_V1.includes(status);
|
|
864
|
+
}
|
|
865
|
+
function rowDeclaresPartialData(reserved) {
|
|
866
|
+
reserved.partialData = ownDataValue(reserved.record, "partial_data");
|
|
867
|
+
return reserved.partialData === true;
|
|
868
|
+
}
|
|
869
|
+
function readRowCurrency(reserved) {
|
|
870
|
+
reserved.currency = ownDataValue(reserved.record, "currency");
|
|
871
|
+
}
|
|
872
|
+
function readRowIdentity(reserved) {
|
|
873
|
+
reserved.mediaBuyId = ownDataValue(reserved.record, "media_buy_id");
|
|
874
|
+
}
|
|
875
|
+
function reservedFieldValue(reserved, field) {
|
|
876
|
+
switch (field) {
|
|
877
|
+
case "media_buy_id":
|
|
878
|
+
return reserved.mediaBuyId;
|
|
879
|
+
case "currency":
|
|
880
|
+
return reserved.currency;
|
|
881
|
+
case "status":
|
|
882
|
+
return reserved.status;
|
|
883
|
+
case "partial_data":
|
|
884
|
+
return reserved.partialData;
|
|
885
|
+
default:
|
|
886
|
+
return reserved.totals;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
function createClaimStore(layout, rowCount) {
|
|
890
|
+
const width = layout.fields.length;
|
|
891
|
+
return {
|
|
892
|
+
layout,
|
|
893
|
+
values: new Array(rowCount * width),
|
|
894
|
+
flags: new Uint8Array(rowCount * width)
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
function fieldSlotOf(snapshot, field) {
|
|
898
|
+
return snapshot.store.layout.indexOf.get(field) ?? -1;
|
|
899
|
+
}
|
|
900
|
+
function slotValue(snapshot, slot) {
|
|
901
|
+
return slot < 0 || snapshot.offset < 0 ? void 0 : snapshot.store.values[snapshot.offset + slot];
|
|
902
|
+
}
|
|
903
|
+
function slotFlags(snapshot, slot) {
|
|
904
|
+
return slot < 0 || snapshot.offset < 0 ? 0 : snapshot.store.flags[snapshot.offset + slot] ?? 0;
|
|
905
|
+
}
|
|
906
|
+
function snapshotFieldValue(snapshot, field) {
|
|
907
|
+
return slotValue(snapshot, fieldSlotOf(snapshot, field));
|
|
908
|
+
}
|
|
909
|
+
function captureRowSnapshot(reserved, store, rowIndex, strictClaims, chargeScan) {
|
|
910
|
+
if (!reserved) return void 0;
|
|
911
|
+
readRowIdentity(reserved);
|
|
912
|
+
const { record } = reserved;
|
|
913
|
+
const layout = store.layout;
|
|
914
|
+
const offset = rowIndex * layout.fields.length;
|
|
915
|
+
let totalsObserved = false;
|
|
916
|
+
let totalsRecord;
|
|
917
|
+
let totalsAliasesRow = false;
|
|
918
|
+
const observeTotals = () => {
|
|
919
|
+
if (!totalsObserved) {
|
|
920
|
+
totalsObserved = true;
|
|
921
|
+
reserved.totals = ownDataValue(record, "totals");
|
|
922
|
+
totalsRecord = typeof reserved.totals === "object" && reserved.totals !== null ? reserved.totals : void 0;
|
|
923
|
+
totalsAliasesRow = totalsRecord === record;
|
|
924
|
+
}
|
|
925
|
+
return reserved.totals;
|
|
926
|
+
};
|
|
927
|
+
for (let slot = 0; slot < layout.fields.length; slot += 1) {
|
|
928
|
+
const field = layout.fields[slot];
|
|
929
|
+
const direct = layout.reservedFields.has(field) ? claimOfValue(field === "totals" ? observeTotals() : reservedFieldValue(reserved, field)) : ownDataClaim(record, field);
|
|
930
|
+
const measurePasses = strictClaims ? 2 : 1;
|
|
931
|
+
chargeScan(measureScanWidth(direct.value) * measurePasses);
|
|
932
|
+
const measuredDirect = measureClaim(direct.value, strictClaims);
|
|
933
|
+
let nested = UNCLAIMED_V1;
|
|
934
|
+
let measuredNested = UNMEASURED_CLAIM_V1;
|
|
935
|
+
if (strictClaims || !measuredDirect.valid) {
|
|
936
|
+
observeTotals();
|
|
937
|
+
if (totalsRecord !== void 0) {
|
|
938
|
+
if (totalsAliasesRow) {
|
|
939
|
+
nested = direct;
|
|
940
|
+
measuredNested = measuredDirect;
|
|
941
|
+
} else {
|
|
942
|
+
nested = ownDataClaim(totalsRecord, field);
|
|
943
|
+
chargeScan(measureScanWidth(nested.value) * measurePasses);
|
|
944
|
+
measuredNested = measureClaim(nested.value, strictClaims);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
const resolved = measuredDirect.valid ? measuredDirect : measuredNested.valid ? measuredNested : void 0;
|
|
949
|
+
const claimed = direct.claimed ? measuredDirect : measuredNested;
|
|
950
|
+
let bits = 0;
|
|
951
|
+
if (direct.claimed) bits |= CLAIM_DIRECT_CLAIMED_V1;
|
|
952
|
+
if (nested.claimed) bits |= CLAIM_NESTED_CLAIMED_V1;
|
|
953
|
+
if (measuredDirect.valid) bits |= CLAIM_DIRECT_VALID_V1;
|
|
954
|
+
if (measuredNested.valid) bits |= CLAIM_NESTED_VALID_V1;
|
|
955
|
+
if (resolved?.isZero === true) bits |= CLAIM_VALUE_IS_ZERO_V1;
|
|
956
|
+
if (claimed.valid && claimed.isZero) bits |= CLAIM_CLAIM_IS_ZERO_V1;
|
|
957
|
+
if (strictClaims && direct.claimed && nested.claimed && measuredDirect.valid && measuredNested.valid && !Object.is(direct.value, nested.value)) {
|
|
958
|
+
chargeScan(canonicalScanWidth(direct.value) + canonicalScanWidth(nested.value));
|
|
959
|
+
const canonicalDirect = canonicalDecimalEvidence(measuredDirect.value);
|
|
960
|
+
const canonicalNested = canonicalDecimalEvidence(measuredNested.value);
|
|
961
|
+
if (canonicalDirect === void 0 || canonicalDirect !== canonicalNested) bits |= CLAIM_DISAGREE_V1;
|
|
962
|
+
}
|
|
963
|
+
store.values[offset + slot] = resolved?.value;
|
|
964
|
+
store.flags[offset + slot] = bits;
|
|
965
|
+
}
|
|
966
|
+
return {
|
|
967
|
+
store,
|
|
968
|
+
offset,
|
|
969
|
+
mediaBuyId: typeof reserved.mediaBuyId === "string" ? reserved.mediaBuyId : void 0
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
function captureRowIdentityOnly(reserved, store) {
|
|
973
|
+
if (!reserved) return void 0;
|
|
974
|
+
reserved.mediaBuyId = ownDataValue(reserved.record, "media_buy_id");
|
|
975
|
+
return {
|
|
976
|
+
store,
|
|
977
|
+
offset: INLINE_NO_CLAIMS_OFFSET_V1,
|
|
978
|
+
mediaBuyId: typeof reserved.mediaBuyId === "string" ? reserved.mediaBuyId : void 0
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
function claimOfValue(value) {
|
|
982
|
+
return value === void 0 ? UNCLAIMED_V1 : { claimed: true, value };
|
|
983
|
+
}
|
|
984
|
+
function asRowRecord(row) {
|
|
985
|
+
return typeof row !== "object" || row === null || Array.isArray(row) ? void 0 : row;
|
|
986
|
+
}
|
|
987
|
+
function boundedLowerCaseStatus(status) {
|
|
988
|
+
return typeof status === "string" && status.length <= INLINE_MAX_STATUS_CHARS_V1 ? status.toLowerCase() : void 0;
|
|
989
|
+
}
|
|
990
|
+
const UNMEASURED_CLAIM_V1 = { value: void 0, valid: false, isZero: false };
|
|
991
|
+
function measureClaim(value, strictClaims) {
|
|
992
|
+
if (!isEvidenceValue(value)) return UNMEASURED_CLAIM_V1;
|
|
993
|
+
return { value, valid: true, isZero: strictClaims ? isZeroEvidenceValue(value) : false };
|
|
994
|
+
}
|
|
995
|
+
function measureScanWidth(value) {
|
|
996
|
+
return typeof value === "string" ? value.length + 1 : 1;
|
|
997
|
+
}
|
|
998
|
+
function canonicalScanWidth(value) {
|
|
999
|
+
if (typeof value === "string") return value.length + 1;
|
|
1000
|
+
if (typeof value !== "number") return 1;
|
|
1001
|
+
return numericScanUnits(value);
|
|
1002
|
+
}
|
|
1003
|
+
function numericScanUnits(value) {
|
|
1004
|
+
const printed = String(value);
|
|
1005
|
+
const exponent = /[eE]([+-]?\d+)$/.exec(printed);
|
|
1006
|
+
return printed.length + (exponent ? Math.abs(Number(exponent[1])) : 0) + 1;
|
|
1007
|
+
}
|
|
1008
|
+
function workUnitsExceedCap(count, unitsEach, cap) {
|
|
1009
|
+
return unitsEach > 0 && count > Math.floor(cap / unitsEach);
|
|
1010
|
+
}
|
|
1011
|
+
function validationWorkExceedsCap(sourceSnapshots, auxiliarySnapshots, request, includeAuxiliary, cap) {
|
|
1012
|
+
const unitsPerVisit = request.requestedMetrics.length + request.requestedDimensions.length;
|
|
1013
|
+
if (unitsPerVisit === 0) return false;
|
|
1014
|
+
const perConstituentCap = Math.floor(cap / unitsPerVisit);
|
|
1015
|
+
const sourceCounts = countSnapshotsByMediaBuyId(sourceSnapshots);
|
|
1016
|
+
const auxiliaryCounts = includeAuxiliary ? countSnapshotsByMediaBuyId(auxiliarySnapshots) : void 0;
|
|
1017
|
+
let work = 0;
|
|
1018
|
+
for (const constituent of request.coverage.constituents) {
|
|
1019
|
+
if (!constituent.mediaBuyId) continue;
|
|
1020
|
+
const visits = (sourceCounts.get(constituent.mediaBuyId) ?? 0) + (auxiliaryCounts?.get(constituent.mediaBuyId) ?? 0);
|
|
1021
|
+
if (visits > perConstituentCap) return true;
|
|
1022
|
+
work += visits * unitsPerVisit;
|
|
1023
|
+
if (work > cap) return true;
|
|
1024
|
+
}
|
|
1025
|
+
return false;
|
|
1026
|
+
}
|
|
1027
|
+
function countSnapshotsByMediaBuyId(snapshots) {
|
|
1028
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1029
|
+
for (const snapshot of snapshots) {
|
|
1030
|
+
if (snapshot?.mediaBuyId === void 0) continue;
|
|
1031
|
+
counts.set(snapshot.mediaBuyId, (counts.get(snapshot.mediaBuyId) ?? 0) + 1);
|
|
1032
|
+
}
|
|
1033
|
+
return counts;
|
|
1034
|
+
}
|
|
1035
|
+
function groupSnapshotsByMediaBuyId(snapshots, admittedMediaBuyIds) {
|
|
1036
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
1037
|
+
for (const snapshot of snapshots) {
|
|
1038
|
+
if (!snapshot) continue;
|
|
1039
|
+
const mediaBuyId = snapshot.mediaBuyId;
|
|
1040
|
+
if (mediaBuyId === void 0 || !admittedMediaBuyIds.has(mediaBuyId)) continue;
|
|
1041
|
+
const existing = grouped.get(mediaBuyId);
|
|
1042
|
+
if (existing) existing.push(snapshot);
|
|
1043
|
+
else grouped.set(mediaBuyId, [snapshot]);
|
|
1044
|
+
}
|
|
1045
|
+
return grouped;
|
|
1046
|
+
}
|
|
1047
|
+
function snapshotHasDimension(snapshot, dimension) {
|
|
1048
|
+
return dimension === "media_buy_id" ? snapshot.mediaBuyId !== void 0 : snapshotFieldValue(snapshot, dimension) !== void 0;
|
|
1049
|
+
}
|
|
1050
|
+
function validateSnapshotsAgainstAvailabilityEvidence(sourceSnapshotsByMediaBuyId, auxiliarySnapshotsByMediaBuyId, request, cells) {
|
|
1051
|
+
const cellsByConstituent = /* @__PURE__ */ new Map();
|
|
1052
|
+
for (const constituent of request.coverage.constituents) cellsByConstituent.set(constituent.constituentId, []);
|
|
1053
|
+
for (const cell of cells) cellsByConstituent.get(cell.constituent_id)?.push(cell);
|
|
1054
|
+
let integrity = false;
|
|
1055
|
+
for (const constituent of request.coverage.constituents) {
|
|
1056
|
+
const sourceRows = constituent.mediaBuyId ? sourceSnapshotsByMediaBuyId.get(constituent.mediaBuyId) ?? NO_SNAPSHOTS : NO_SNAPSHOTS;
|
|
1057
|
+
const auxiliaryRows = constituent.mediaBuyId ? auxiliarySnapshotsByMediaBuyId.get(constituent.mediaBuyId) ?? NO_SNAPSHOTS : NO_SNAPSHOTS;
|
|
1058
|
+
for (const cell of cellsByConstituent.get(constituent.constituentId) ?? []) {
|
|
1059
|
+
if (cell.status === "present" && sourceRows.length === 0) return "partial";
|
|
1060
|
+
for (const snapshot of sourceRows) {
|
|
1061
|
+
const verdict = cellVerdictForSnapshot(cell, snapshot, true);
|
|
1062
|
+
if (verdict === "partial") return "partial";
|
|
1063
|
+
if (verdict === "integrity") integrity = true;
|
|
1064
|
+
}
|
|
1065
|
+
for (const snapshot of auxiliaryRows) {
|
|
1066
|
+
const verdict = cellVerdictForSnapshot(cell, snapshot, false);
|
|
1067
|
+
if (verdict === "partial") return "partial";
|
|
1068
|
+
if (verdict === "integrity") integrity = true;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
return integrity ? "integrity" : void 0;
|
|
1073
|
+
}
|
|
1074
|
+
function cellVerdictForSnapshot(cell, snapshot, isSourceRow) {
|
|
1075
|
+
const slot = fieldSlotOf(snapshot, cell.metric);
|
|
1076
|
+
const flags = slotFlags(snapshot, slot);
|
|
1077
|
+
if (isSourceRow) {
|
|
1078
|
+
if (cell.status === "present" && slotValue(snapshot, slot) === void 0) return "partial";
|
|
1079
|
+
if (cell.status === "explicit_zero" && (flags & CLAIM_VALUE_IS_ZERO_V1) === 0) return "integrity";
|
|
1080
|
+
}
|
|
1081
|
+
const directClaimed = (flags & CLAIM_DIRECT_CLAIMED_V1) !== 0;
|
|
1082
|
+
const nestedClaimed = (flags & CLAIM_NESTED_CLAIMED_V1) !== 0;
|
|
1083
|
+
const directValid = (flags & CLAIM_DIRECT_VALID_V1) !== 0;
|
|
1084
|
+
const nestedValid = (flags & CLAIM_NESTED_VALID_V1) !== 0;
|
|
1085
|
+
if (directClaimed && !directValid || nestedClaimed && !nestedValid) return "integrity";
|
|
1086
|
+
const claimValid = directClaimed ? directValid : nestedValid;
|
|
1087
|
+
if ((flags & CLAIM_DISAGREE_V1) !== 0) return "integrity";
|
|
1088
|
+
if (!claimValid) return void 0;
|
|
1089
|
+
if (cell.status === "explicit_zero" && (flags & CLAIM_CLAIM_IS_ZERO_V1) === 0) return "integrity";
|
|
1090
|
+
return INLINE_UNAVAILABLE_CELL_STATUSES_V1.includes(cell.status) ? "integrity" : void 0;
|
|
1091
|
+
}
|
|
1092
|
+
function projectInlineAvailabilityEvidence(cells, request, declaredMetrics, deliveryDates, manifestDataThrough, rowCount, constituentIdsWithRows) {
|
|
1093
|
+
const startMs = Date.parse(request.period.start);
|
|
1094
|
+
const manifestDataThroughMs = Date.parse(manifestDataThrough);
|
|
1095
|
+
const metricAvailability = cells.map((cell) => {
|
|
1096
|
+
const metric = declaredMetrics.get(cell.metric);
|
|
1097
|
+
if (!metric) throw new TypeError(`Offering does not declare ${cell.metric}`);
|
|
1098
|
+
const dataThrough = cell.data_through ? normalizeDeliveryInstant(cell.data_through, deliveryDates, request.period) : void 0;
|
|
1099
|
+
const dataThroughMs = dataThrough === void 0 ? void 0 : Date.parse(dataThrough);
|
|
1100
|
+
if (dataThroughMs !== void 0 && (!Number.isFinite(dataThroughMs) || dataThroughMs < startMs || dataThroughMs > manifestDataThroughMs || ["present", "explicit_zero"].includes(cell.status) && constituentIdsWithRows.has(cell.constituent_id) && dataThroughMs === startMs)) {
|
|
1101
|
+
throw new TypeError("Availability dataThrough exceeds the manifest window");
|
|
1102
|
+
}
|
|
1103
|
+
return {
|
|
1104
|
+
constituentId: cell.constituent_id,
|
|
1105
|
+
metric: cell.metric,
|
|
1106
|
+
semanticContractId: metric.semanticContractId,
|
|
1107
|
+
semanticContractVersion: metric.semanticContractVersion,
|
|
1108
|
+
semanticContractSha256: metric.semanticContractSha256,
|
|
1109
|
+
status: cell.status,
|
|
1110
|
+
...dataThrough ? { dataThrough } : {},
|
|
1111
|
+
...cell.reason ? { reason: cell.reason } : {}
|
|
1112
|
+
};
|
|
1113
|
+
});
|
|
1114
|
+
const coverageConstituents = request.coverage.constituents.map((constituent) => {
|
|
1115
|
+
const constituentCells = metricAvailability.filter((cell) => cell.constituentId === constituent.constituentId);
|
|
1116
|
+
const status = rollUpInlineConstituentStatus(constituentCells.map((cell) => cell.status));
|
|
1117
|
+
const dataThrough = earliestDataThrough(constituentCells);
|
|
1118
|
+
const reason = constituentCells.find((cell) => cell.reason)?.reason;
|
|
1119
|
+
if (!["present", "explicit_zero"].includes(status) && !reason) {
|
|
1120
|
+
throw new TypeError("Unavailable constituent roll-up requires supplied evidence");
|
|
1121
|
+
}
|
|
1122
|
+
return {
|
|
1123
|
+
...constituent,
|
|
1124
|
+
status,
|
|
1125
|
+
...dataThrough ? { dataThrough } : {},
|
|
1126
|
+
...reason && !["present", "explicit_zero"].includes(status) ? { reason } : {}
|
|
1127
|
+
};
|
|
1128
|
+
});
|
|
1129
|
+
const allCellsExplicitZero = metricAvailability.every((cell) => cell.status === "explicit_zero");
|
|
1130
|
+
if (rowCount === 0 && metricAvailability.some((cell) => ["present", "explicit_zero"].includes(cell.status)) && !allCellsExplicitZero) {
|
|
1131
|
+
throw new TypeError("Zero-row evidence has contradictory available cells");
|
|
1132
|
+
}
|
|
1133
|
+
const fullyCovered = coverageConstituents.filter(
|
|
1134
|
+
(constituent) => ["present", "explicit_zero"].includes(constituent.status)
|
|
1135
|
+
).length;
|
|
1136
|
+
const someCoverage = fullyCovered > 0 || coverageConstituents.some((constituent) => constituent.status === "partial");
|
|
1137
|
+
return {
|
|
1138
|
+
metricAvailability,
|
|
1139
|
+
coverageConstituents,
|
|
1140
|
+
coverageStatus: fullyCovered === coverageConstituents.length ? "full" : someCoverage ? "partial" : "none",
|
|
1141
|
+
explicitZero: rowCount === 0 && allCellsExplicitZero
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1144
|
+
function projectLegacyAvailability(request, declaredMetrics, dataThrough, rowCount) {
|
|
1145
|
+
const explicitZero = rowCount === 0;
|
|
385
1146
|
const status = explicitZero ? "explicit_zero" : "present";
|
|
386
|
-
|
|
387
|
-
...constituent,
|
|
388
|
-
status,
|
|
389
|
-
dataThrough
|
|
390
|
-
}));
|
|
391
|
-
const declaredMetrics = new Map(offering.metrics.map((metric) => [metric.name, metric]));
|
|
392
|
-
const built = (0, import_builder.buildReportingSourceManifestV1)({
|
|
393
|
-
level: "basic",
|
|
394
|
-
request,
|
|
395
|
-
stagedCommitRef: `inline-manifest-${executionNamespace.slice(0, 32)}`,
|
|
396
|
-
objects: [object],
|
|
397
|
-
completeness: {
|
|
398
|
-
terminal: true,
|
|
399
|
-
rowsComplete: true,
|
|
400
|
-
requestedGroupsComplete: true
|
|
401
|
-
},
|
|
402
|
-
controlTotals: [],
|
|
1147
|
+
return {
|
|
403
1148
|
metricAvailability: request.coverage.constituents.flatMap(
|
|
404
1149
|
(constituent) => request.requestedMetrics.map((metricName) => {
|
|
405
1150
|
const metric = declaredMetrics.get(metricName);
|
|
@@ -415,35 +1160,34 @@ async function executeAndSeal(deliveryFetch, offering, format, request, delivery
|
|
|
415
1160
|
};
|
|
416
1161
|
})
|
|
417
1162
|
),
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
owner: "adapter",
|
|
426
|
-
basis: request.publicationClass === "PROVISIONAL_SNAPSHOT" ? "provisional_observation" : "source_declared",
|
|
427
|
-
observedAt,
|
|
428
|
-
...request.publicationClass === "AUTHORITATIVE" ? { evidenceRef: "get_media_buy_delivery.is_final" } : {}
|
|
429
|
-
},
|
|
430
|
-
explicitZero,
|
|
431
|
-
acquiredAt,
|
|
432
|
-
...explicitZero ? {} : { eventTimeRange: { start: request.period.start, end: dataThrough } },
|
|
433
|
-
warnings: []
|
|
434
|
-
});
|
|
435
|
-
if (Date.parse(deadlineAt) <= Date.now()) {
|
|
436
|
-
return failure("DEADLINE_EXCEEDED", "retryable", "Inline reporting execution deadline elapsed");
|
|
437
|
-
}
|
|
438
|
-
storage.objects.set(objectRef, { request: structuredClone(request), generation, bytes: Uint8Array.from(bytes) });
|
|
439
|
-
storage.totalBytes += bytes.byteLength;
|
|
440
|
-
storage.scopeBytes.set(scopeKey, (storage.scopeBytes.get(scopeKey) ?? 0) + bytes.byteLength);
|
|
441
|
-
return {
|
|
442
|
-
ok: true,
|
|
443
|
-
response: (0, import_source.completedReportingSourceResponseV1)({ request, manifest: built.reference }),
|
|
444
|
-
manifestBytes: built.manifestBytes
|
|
1163
|
+
coverageConstituents: request.coverage.constituents.map((constituent) => ({
|
|
1164
|
+
...constituent,
|
|
1165
|
+
status,
|
|
1166
|
+
dataThrough
|
|
1167
|
+
})),
|
|
1168
|
+
coverageStatus: "full",
|
|
1169
|
+
explicitZero
|
|
445
1170
|
};
|
|
446
1171
|
}
|
|
1172
|
+
function rollUpInlineConstituentStatus(statuses) {
|
|
1173
|
+
if (statuses.every((status) => status === "explicit_zero")) return "explicit_zero";
|
|
1174
|
+
if (statuses.every((status) => status === "present" || status === "explicit_zero")) return "present";
|
|
1175
|
+
if (statuses.every((status) => status === "unsupported")) return "unsupported";
|
|
1176
|
+
if (statuses.every((status) => status === "missing")) return "missing";
|
|
1177
|
+
if (statuses.every((status) => ["unsupported", "delayed", "missing"].includes(status))) return "delayed";
|
|
1178
|
+
if (statuses.every((status) => ["unsupported", "delayed", "stale", "missing"].includes(status))) return "stale";
|
|
1179
|
+
return "partial";
|
|
1180
|
+
}
|
|
1181
|
+
function earliestDataThrough(cells) {
|
|
1182
|
+
return cells.reduce((earliest, cell) => {
|
|
1183
|
+
if (!cell.dataThrough) return earliest;
|
|
1184
|
+
if (!earliest || Date.parse(cell.dataThrough) < Date.parse(earliest)) return cell.dataThrough;
|
|
1185
|
+
return earliest;
|
|
1186
|
+
}, void 0);
|
|
1187
|
+
}
|
|
1188
|
+
function availabilityCellKey(constituentId, metric) {
|
|
1189
|
+
return `${constituentId}\0${metric}`;
|
|
1190
|
+
}
|
|
447
1191
|
function encodeRows(rows, mediaType, maxBytes) {
|
|
448
1192
|
if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) throw new RangeError("Inline staging capacity exhausted");
|
|
449
1193
|
const chunks = [];
|
|
@@ -549,29 +1293,50 @@ async function awaitInlineExecution(entry, signal, deadlineAt) {
|
|
|
549
1293
|
if (releaseWaiter) entry.waiters -= 1;
|
|
550
1294
|
}
|
|
551
1295
|
}
|
|
552
|
-
function
|
|
553
|
-
|
|
554
|
-
const value = ownDataValue(row, "media_buy_id");
|
|
555
|
-
return typeof value === "string" ? value : void 0;
|
|
1296
|
+
function isEvidenceValue(value) {
|
|
1297
|
+
return typeof value === "number" && Number.isFinite(value) || typeof value === "string" && value.length > 0 && Buffer.byteLength(value, "utf8") <= INLINE_MAX_OBJECT_BYTES_V1;
|
|
556
1298
|
}
|
|
557
|
-
function
|
|
558
|
-
|
|
1299
|
+
function canonicalDecimalEvidence(value) {
|
|
1300
|
+
let raw;
|
|
1301
|
+
if (typeof value === "number") {
|
|
1302
|
+
if (!Number.isFinite(value)) return void 0;
|
|
1303
|
+
raw = plainDecimalNumberEvidence(value);
|
|
1304
|
+
} else {
|
|
1305
|
+
raw = value.trim();
|
|
1306
|
+
}
|
|
1307
|
+
const parts = /^(-?)(\d+)(?:\.(\d+))?$/.exec(raw);
|
|
1308
|
+
if (!parts) return void 0;
|
|
1309
|
+
const integer = trimLeadingZeroDigits(parts[2] ?? "");
|
|
1310
|
+
const fraction = trimTrailingZeroDigits(parts[3] ?? "");
|
|
1311
|
+
const magnitude = fraction ? `${integer}.${fraction}` : integer;
|
|
1312
|
+
return magnitude === "0" ? "0" : `${parts[1] ?? ""}${magnitude}`;
|
|
559
1313
|
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
const totals = ownDataValue(record, "totals");
|
|
566
|
-
if (typeof totals !== "object" || totals === null) return void 0;
|
|
567
|
-
const nested = ownDataValue(totals, field);
|
|
568
|
-
return isEvidenceValue(nested) ? nested : void 0;
|
|
1314
|
+
const ZERO_CHAR_CODE = 48;
|
|
1315
|
+
function trimLeadingZeroDigits(digits) {
|
|
1316
|
+
let start = 0;
|
|
1317
|
+
while (start + 1 < digits.length && digits.charCodeAt(start) === ZERO_CHAR_CODE) start += 1;
|
|
1318
|
+
return digits.slice(start);
|
|
569
1319
|
}
|
|
570
|
-
function
|
|
571
|
-
|
|
1320
|
+
function trimTrailingZeroDigits(digits) {
|
|
1321
|
+
let end = digits.length;
|
|
1322
|
+
while (end > 0 && digits.charCodeAt(end - 1) === ZERO_CHAR_CODE) end -= 1;
|
|
1323
|
+
return digits.slice(0, end);
|
|
1324
|
+
}
|
|
1325
|
+
function plainDecimalNumberEvidence(value) {
|
|
1326
|
+
const raw = String(value);
|
|
1327
|
+
const parts = /^(-?)(\d+)(?:\.(\d+))?[eE]([+-]?\d+)$/.exec(raw);
|
|
1328
|
+
if (!parts) return raw;
|
|
1329
|
+
const exponent = Number(parts[4]);
|
|
1330
|
+
if (!Number.isInteger(exponent) || Math.abs(exponent) > INLINE_MAX_DECIMAL_EXPONENT_V1) return raw;
|
|
1331
|
+
const sign = parts[1] ?? "";
|
|
1332
|
+
const digits = `${parts[2] ?? ""}${parts[3] ?? ""}`;
|
|
1333
|
+
const pointIndex = (parts[2] ?? "").length + exponent;
|
|
1334
|
+
if (pointIndex <= 0) return `${sign}0.${"0".repeat(-pointIndex)}${digits}`;
|
|
1335
|
+
if (pointIndex >= digits.length) return `${sign}${digits}${"0".repeat(pointIndex - digits.length)}`;
|
|
1336
|
+
return `${sign}${digits.slice(0, pointIndex)}.${digits.slice(pointIndex)}`;
|
|
572
1337
|
}
|
|
573
|
-
function
|
|
574
|
-
return
|
|
1338
|
+
function isZeroEvidenceValue(value) {
|
|
1339
|
+
return typeof value === "number" ? value === 0 : /^\s*-?0+(?:\.0+)?\s*$/.test(value);
|
|
575
1340
|
}
|
|
576
1341
|
function isRows(value) {
|
|
577
1342
|
return Array.isArray(value);
|
|
@@ -580,41 +1345,122 @@ function ownDataValue(record, field) {
|
|
|
580
1345
|
const descriptor = Object.getOwnPropertyDescriptor(record, field);
|
|
581
1346
|
return descriptor && "value" in descriptor ? descriptor.value : void 0;
|
|
582
1347
|
}
|
|
583
|
-
function
|
|
584
|
-
|
|
585
|
-
|
|
1348
|
+
function ownDataClaim(record, field) {
|
|
1349
|
+
const descriptor = Object.getOwnPropertyDescriptor(record, field);
|
|
1350
|
+
return descriptor && "value" in descriptor && descriptor.value !== void 0 ? { claimed: true, value: descriptor.value } : { claimed: false };
|
|
1351
|
+
}
|
|
1352
|
+
function snapshotOwnDataObject(record, allowedKeys) {
|
|
1353
|
+
const keys = Reflect.ownKeys(record);
|
|
1354
|
+
if (keys.length > INLINE_MAX_EVIDENCE_OBJECT_KEYS_V1) {
|
|
1355
|
+
throw new TypeError("Availability evidence object declares too many keys");
|
|
1356
|
+
}
|
|
1357
|
+
for (const key of keys) {
|
|
1358
|
+
if (typeof key !== "string" || !allowedKeys.includes(key)) {
|
|
1359
|
+
throw new TypeError("Availability evidence object declares an unknown key");
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
const snapshot = {};
|
|
1363
|
+
for (const key of keys) {
|
|
1364
|
+
const descriptor = Object.getOwnPropertyDescriptor(record, key);
|
|
1365
|
+
if (!descriptor || !("value" in descriptor)) throw new TypeError("Availability evidence field is not readable");
|
|
1366
|
+
if (typeof descriptor.value === "string" && descriptor.value.length > INLINE_MAX_EVIDENCE_FIELD_CHARS_V1) {
|
|
1367
|
+
throw new TypeError("Availability evidence field exceeds its bounded length");
|
|
1368
|
+
}
|
|
1369
|
+
snapshot[key] = descriptor.value;
|
|
1370
|
+
}
|
|
1371
|
+
return snapshot;
|
|
1372
|
+
}
|
|
1373
|
+
function createResponseFieldReader(record) {
|
|
1374
|
+
const observed = /* @__PURE__ */ new Map();
|
|
1375
|
+
return (field) => {
|
|
1376
|
+
if (observed.has(field)) return observed.get(field);
|
|
1377
|
+
const value = record?.[field];
|
|
1378
|
+
observed.set(field, value);
|
|
1379
|
+
return value;
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
function asStringOrUndefined(value) {
|
|
586
1383
|
return typeof value === "string" ? value : void 0;
|
|
587
1384
|
}
|
|
588
|
-
function
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
return
|
|
593
|
-
}
|
|
594
|
-
function
|
|
595
|
-
if (
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
1385
|
+
function looseCount(value) {
|
|
1386
|
+
return value ?? 0;
|
|
1387
|
+
}
|
|
1388
|
+
function lengthOfUnknown(value) {
|
|
1389
|
+
return value?.length;
|
|
1390
|
+
}
|
|
1391
|
+
function boundedCollectionLength(rows) {
|
|
1392
|
+
if (rows === void 0) return 0;
|
|
1393
|
+
const declared = rows.length;
|
|
1394
|
+
return typeof declared === "number" && Number.isSafeInteger(declared) && declared >= 0 ? declared : void 0;
|
|
1395
|
+
}
|
|
1396
|
+
function captureRowCollection(rows, declaredLength) {
|
|
1397
|
+
const captured = new Array(declaredLength);
|
|
1398
|
+
for (let index = 0; index < declaredLength; index += 1) captured[index] = rows[index];
|
|
1399
|
+
return captured;
|
|
1400
|
+
}
|
|
1401
|
+
function resolveOwnDataSlot(record, field) {
|
|
1402
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1403
|
+
let current = record;
|
|
1404
|
+
for (let depth = 0; current !== null; depth += 1) {
|
|
1405
|
+
if (depth >= INLINE_MAX_PROTOTYPE_CHAIN_DEPTH_V1 || visited.has(current)) return { kind: "unreadable" };
|
|
1406
|
+
visited.add(current);
|
|
1407
|
+
let descriptor;
|
|
1408
|
+
let prototype = null;
|
|
1409
|
+
try {
|
|
1410
|
+
descriptor = Object.getOwnPropertyDescriptor(current, field);
|
|
1411
|
+
if (!descriptor) prototype = Object.getPrototypeOf(current);
|
|
1412
|
+
} catch {
|
|
1413
|
+
return { kind: "unreadable" };
|
|
1414
|
+
}
|
|
1415
|
+
if (descriptor) {
|
|
1416
|
+
if (!("value" in descriptor)) return { kind: "unreadable" };
|
|
1417
|
+
if (descriptor.value === void 0) return { kind: "absent" };
|
|
1418
|
+
return current === record ? { kind: "data", value: descriptor.value } : { kind: "unreadable" };
|
|
1419
|
+
}
|
|
1420
|
+
current = prototype;
|
|
1421
|
+
}
|
|
1422
|
+
return { kind: "absent" };
|
|
1423
|
+
}
|
|
1424
|
+
function projectSnapshotRow(snapshot, request, consumeBudget, options) {
|
|
1425
|
+
if (!snapshot) throw new TypeError("Invalid row");
|
|
1426
|
+
const projected = { media_buy_id: snapshot.mediaBuyId };
|
|
1427
|
+
if (options.includeDimensions) {
|
|
1428
|
+
for (const dimension of request.requestedDimensions) {
|
|
1429
|
+
if (dimension === "media_buy_id") continue;
|
|
1430
|
+
const value = snapshotFieldValue(snapshot, dimension);
|
|
1431
|
+
if (value === void 0) {
|
|
1432
|
+
if (options.allowMissingDimensions) continue;
|
|
1433
|
+
throw new TypeError("Invalid dimension evidence");
|
|
1434
|
+
}
|
|
1435
|
+
consumeBudget(jsonEvidenceUpperBound(value));
|
|
1436
|
+
projected[dimension] = value;
|
|
1437
|
+
}
|
|
604
1438
|
}
|
|
605
|
-
const totals = ownDataValue(record, "totals");
|
|
606
1439
|
const projectedTotals = {};
|
|
607
1440
|
for (const metric of request.requestedMetrics) {
|
|
608
|
-
const
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
1441
|
+
const slot = fieldSlotOf(snapshot, metric);
|
|
1442
|
+
const flags = slotFlags(snapshot, slot);
|
|
1443
|
+
const directClaimed = (flags & CLAIM_DIRECT_CLAIMED_V1) !== 0;
|
|
1444
|
+
const directValid = (flags & CLAIM_DIRECT_VALID_V1) !== 0;
|
|
1445
|
+
const value = slotValue(snapshot, slot);
|
|
1446
|
+
let directValue = false;
|
|
1447
|
+
if (options.strictMetricClaims) {
|
|
1448
|
+
if (directClaimed && !directValid) throw new TypeError("Invalid metric evidence");
|
|
1449
|
+
if ((flags & CLAIM_NESTED_CLAIMED_V1) !== 0 && (flags & CLAIM_NESTED_VALID_V1) === 0) {
|
|
1450
|
+
throw new TypeError("Invalid metric evidence");
|
|
1451
|
+
}
|
|
1452
|
+
if ((flags & CLAIM_DISAGREE_V1) !== 0) throw new TypeError("Contradictory metric evidence");
|
|
1453
|
+
directValue = directClaimed;
|
|
1454
|
+
} else {
|
|
1455
|
+
directValue = directValid;
|
|
1456
|
+
}
|
|
1457
|
+
if (value === void 0) {
|
|
1458
|
+
if (options.allowMissingMetrics) continue;
|
|
1459
|
+
throw new TypeError("Invalid metric evidence");
|
|
613
1460
|
}
|
|
614
|
-
|
|
615
|
-
if (
|
|
616
|
-
|
|
617
|
-
projectedTotals[metric] = total;
|
|
1461
|
+
consumeBudget(jsonEvidenceUpperBound(value));
|
|
1462
|
+
if (directValue) projected[metric] = value;
|
|
1463
|
+
else projectedTotals[metric] = value;
|
|
618
1464
|
}
|
|
619
1465
|
if (Object.keys(projectedTotals).length > 0) projected.totals = projectedTotals;
|
|
620
1466
|
return projected;
|
|
@@ -625,6 +1471,154 @@ function inlineDeliveryDates(request) {
|
|
|
625
1471
|
if (start !== request.period.sourceLocalDate) throw new RangeError("sourceLocalDate does not match period start");
|
|
626
1472
|
return { start, end };
|
|
627
1473
|
}
|
|
1474
|
+
function stagedObjectRef(executionKey) {
|
|
1475
|
+
return `inline-${executionKey.slice(0, 32)}`;
|
|
1476
|
+
}
|
|
1477
|
+
function stagedBytesOf(storage, executionKey) {
|
|
1478
|
+
return storage.objects.get(stagedObjectRef(executionKey))?.bytes.byteLength ?? 0;
|
|
1479
|
+
}
|
|
1480
|
+
function planReclaim(executions, excluded, scopeKey) {
|
|
1481
|
+
for (const [key, entry] of executions) {
|
|
1482
|
+
if (entry.pending || entry.waiters > 0 || entry.reservation !== void 0) continue;
|
|
1483
|
+
if (scopeKey !== void 0 && entry.scopeKey !== scopeKey) continue;
|
|
1484
|
+
if (excluded.includes(key)) continue;
|
|
1485
|
+
return key;
|
|
1486
|
+
}
|
|
1487
|
+
return void 0;
|
|
1488
|
+
}
|
|
1489
|
+
function commitReclaim(executions, storage, key) {
|
|
1490
|
+
const entry = executions.get(key);
|
|
1491
|
+
if (!entry) return;
|
|
1492
|
+
executions.delete(key);
|
|
1493
|
+
const objectRef = stagedObjectRef(key);
|
|
1494
|
+
const stored = storage.objects.get(objectRef);
|
|
1495
|
+
if (!stored) return;
|
|
1496
|
+
storage.objects.delete(objectRef);
|
|
1497
|
+
storage.totalBytes -= stored.bytes.byteLength;
|
|
1498
|
+
const remaining = (storage.scopeBytes.get(entry.scopeKey) ?? 0) - stored.bytes.byteLength;
|
|
1499
|
+
if (remaining > 0) storage.scopeBytes.set(entry.scopeKey, remaining);
|
|
1500
|
+
else storage.scopeBytes.delete(entry.scopeKey);
|
|
1501
|
+
}
|
|
1502
|
+
function createAdmissionReclaimer(executions, storage) {
|
|
1503
|
+
const planned = [];
|
|
1504
|
+
const token = {};
|
|
1505
|
+
const owns = (key) => executions.get(key)?.reservation === token;
|
|
1506
|
+
let settled = false;
|
|
1507
|
+
return {
|
|
1508
|
+
plan(scopeKey, scopeOnly, credit = false) {
|
|
1509
|
+
const victim = planReclaim(
|
|
1510
|
+
executions,
|
|
1511
|
+
planned.map((entry2) => entry2.key),
|
|
1512
|
+
scopeOnly ? scopeKey : void 0
|
|
1513
|
+
);
|
|
1514
|
+
if (victim === void 0) return void 0;
|
|
1515
|
+
const entry = executions.get(victim);
|
|
1516
|
+
if (entry) entry.reservation = token;
|
|
1517
|
+
const sameScope = entry?.scopeKey === scopeKey;
|
|
1518
|
+
const bytes = stagedBytesOf(storage, victim);
|
|
1519
|
+
planned.push({
|
|
1520
|
+
key: victim,
|
|
1521
|
+
sameScope,
|
|
1522
|
+
grantedGlobal: credit ? bytes : 0,
|
|
1523
|
+
grantedScope: credit && sameScope ? bytes : 0
|
|
1524
|
+
});
|
|
1525
|
+
return { bytes, sameScope };
|
|
1526
|
+
},
|
|
1527
|
+
plannedInScope(scopeKey) {
|
|
1528
|
+
return planned.filter((entry) => owns(entry.key) && executions.get(entry.key)?.scopeKey === scopeKey).length;
|
|
1529
|
+
},
|
|
1530
|
+
grantReservedBytes(scopeKey) {
|
|
1531
|
+
let global = 0;
|
|
1532
|
+
let scope = 0;
|
|
1533
|
+
for (const victim of planned) {
|
|
1534
|
+
if (!owns(victim.key)) {
|
|
1535
|
+
victim.grantedGlobal = 0;
|
|
1536
|
+
victim.grantedScope = 0;
|
|
1537
|
+
continue;
|
|
1538
|
+
}
|
|
1539
|
+
const bytes = stagedBytesOf(storage, victim.key);
|
|
1540
|
+
const sameScope = executions.get(victim.key)?.scopeKey === scopeKey;
|
|
1541
|
+
victim.grantedGlobal = bytes;
|
|
1542
|
+
victim.grantedScope = sameScope ? bytes : 0;
|
|
1543
|
+
global += bytes;
|
|
1544
|
+
if (sameScope) scope += bytes;
|
|
1545
|
+
}
|
|
1546
|
+
return { global, scope };
|
|
1547
|
+
},
|
|
1548
|
+
commit(scopeKey) {
|
|
1549
|
+
if (settled) return true;
|
|
1550
|
+
const owned = [];
|
|
1551
|
+
const spared = [];
|
|
1552
|
+
for (const victim of planned) {
|
|
1553
|
+
const entry = executions.get(victim.key);
|
|
1554
|
+
if (entry === void 0) {
|
|
1555
|
+
spared.push(victim);
|
|
1556
|
+
continue;
|
|
1557
|
+
}
|
|
1558
|
+
if (entry.reservation !== token || entry.pending || entry.waiters > 0) spared.push(victim);
|
|
1559
|
+
else owned.push(victim.key);
|
|
1560
|
+
}
|
|
1561
|
+
let owedCount = 0;
|
|
1562
|
+
let owedScopeCount = 0;
|
|
1563
|
+
let owedGlobalBytes = 0;
|
|
1564
|
+
let owedScopeBytes = 0;
|
|
1565
|
+
for (const victim of spared) {
|
|
1566
|
+
owedCount += 1;
|
|
1567
|
+
owedGlobalBytes += victim.grantedGlobal;
|
|
1568
|
+
if (victim.sameScope) {
|
|
1569
|
+
owedScopeCount += 1;
|
|
1570
|
+
owedScopeBytes += victim.grantedScope;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
const excluded = planned.map((victim) => victim.key);
|
|
1574
|
+
const replacements = [];
|
|
1575
|
+
const bound = executions.size;
|
|
1576
|
+
for (let attempt = 0; attempt < bound; attempt += 1) {
|
|
1577
|
+
if (owedCount <= 0 && owedScopeCount <= 0 && owedGlobalBytes <= 0 && owedScopeBytes <= 0) break;
|
|
1578
|
+
const needScope = owedScopeCount > 0 || owedScopeBytes > 0;
|
|
1579
|
+
const candidate = planReclaim(executions, [...excluded, ...replacements], needScope ? scopeKey : void 0);
|
|
1580
|
+
if (candidate === void 0) {
|
|
1581
|
+
if (needScope) break;
|
|
1582
|
+
break;
|
|
1583
|
+
}
|
|
1584
|
+
replacements.push(candidate);
|
|
1585
|
+
const bytes = stagedBytesOf(storage, candidate);
|
|
1586
|
+
owedCount -= 1;
|
|
1587
|
+
owedGlobalBytes -= bytes;
|
|
1588
|
+
if (executions.get(candidate)?.scopeKey === scopeKey) {
|
|
1589
|
+
owedScopeCount -= 1;
|
|
1590
|
+
owedScopeBytes -= bytes;
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
settled = true;
|
|
1594
|
+
if (owedCount > 0 || owedScopeCount > 0 || owedGlobalBytes > 0 || owedScopeBytes > 0) {
|
|
1595
|
+
for (const key of owned) {
|
|
1596
|
+
const entry = executions.get(key);
|
|
1597
|
+
if (entry?.reservation === token) entry.reservation = void 0;
|
|
1598
|
+
}
|
|
1599
|
+
planned.length = 0;
|
|
1600
|
+
return false;
|
|
1601
|
+
}
|
|
1602
|
+
for (const key of owned) {
|
|
1603
|
+
const entry = executions.get(key);
|
|
1604
|
+
if (entry?.reservation === token) entry.reservation = void 0;
|
|
1605
|
+
commitReclaim(executions, storage, key);
|
|
1606
|
+
}
|
|
1607
|
+
for (const key of replacements) commitReclaim(executions, storage, key);
|
|
1608
|
+
planned.length = 0;
|
|
1609
|
+
return true;
|
|
1610
|
+
},
|
|
1611
|
+
release() {
|
|
1612
|
+
if (settled) return;
|
|
1613
|
+
settled = true;
|
|
1614
|
+
for (const victim of planned) {
|
|
1615
|
+
const entry = executions.get(victim.key);
|
|
1616
|
+
if (entry?.reservation === token) entry.reservation = void 0;
|
|
1617
|
+
}
|
|
1618
|
+
planned.length = 0;
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
628
1622
|
function sourceLocalMidnightDate(instant, timeZone) {
|
|
629
1623
|
const date = new Date(instant);
|
|
630
1624
|
const parts = Object.fromEntries(
|
|
@@ -645,12 +1639,13 @@ function sourceLocalMidnightDate(instant, timeZone) {
|
|
|
645
1639
|
return `${parts.year}-${parts.month}-${parts.day}`;
|
|
646
1640
|
}
|
|
647
1641
|
function deliveryPeriodBoundaryMatches(actual, wireDate, instant) {
|
|
1642
|
+
if (typeof actual !== "string") return false;
|
|
648
1643
|
return actual === wireDate || Date.parse(actual) === Date.parse(instant);
|
|
649
1644
|
}
|
|
650
1645
|
function normalizeDeliveryInstant(value, deliveryDates, period) {
|
|
651
1646
|
if (value === deliveryDates.start) return period.start;
|
|
652
1647
|
if (value === deliveryDates.end) return period.end;
|
|
653
|
-
return value;
|
|
1648
|
+
return typeof value === "string" ? value : String(value);
|
|
654
1649
|
}
|
|
655
1650
|
function scheduleDeadline(deadlineAt, expire) {
|
|
656
1651
|
let timer;
|
|
@@ -675,7 +1670,10 @@ function jsonEvidenceUpperBound(value) {
|
|
|
675
1670
|
}
|
|
676
1671
|
// Annotate the CommonJS export names for ESM import in node:
|
|
677
1672
|
0 && (module.exports = {
|
|
1673
|
+
INLINE_REPORTING_AVAILABILITY_EVIDENCE_VERSION_V1,
|
|
678
1674
|
InlineReportingSourceError,
|
|
679
1675
|
ReportingSourceNotReadyError,
|
|
680
|
-
createInlineReportingSourceExecutor
|
|
1676
|
+
createInlineReportingSourceExecutor,
|
|
1677
|
+
createInlineReportingSourceExecutorForTestsV1,
|
|
1678
|
+
inlineStagingCapacitiesForTestsV1
|
|
681
1679
|
});
|