@adcp/sdk 12.0.0 → 12.0.1

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.
Files changed (942) hide show
  1. package/dist/lib/adapters/content-standards-adapter.mjs +0 -6
  2. package/dist/lib/adapters/content-standards-adapter.mjs.map +1 -1
  3. package/dist/lib/adapters/derived-account-store.mjs +0 -6
  4. package/dist/lib/adapters/derived-account-store.mjs.map +1 -1
  5. package/dist/lib/adapters/governance-adapter.mjs +0 -6
  6. package/dist/lib/adapters/governance-adapter.mjs.map +1 -1
  7. package/dist/lib/adapters/implicit-account-store.mjs +0 -6
  8. package/dist/lib/adapters/implicit-account-store.mjs.map +1 -1
  9. package/dist/lib/adapters/index.mjs +0 -6
  10. package/dist/lib/adapters/index.mjs.map +1 -1
  11. package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs +0 -6
  12. package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs.map +1 -1
  13. package/dist/lib/adapters/legacy/v2-5/get_products.mjs +0 -6
  14. package/dist/lib/adapters/legacy/v2-5/get_products.mjs.map +1 -1
  15. package/dist/lib/adapters/legacy/v2-5/index.mjs +0 -6
  16. package/dist/lib/adapters/legacy/v2-5/index.mjs.map +1 -1
  17. package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs +0 -6
  18. package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs.map +1 -1
  19. package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs +0 -6
  20. package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs.map +1 -1
  21. package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs +0 -6
  22. package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs.map +1 -1
  23. package/dist/lib/adapters/legacy/v2-5/types.mjs +0 -6
  24. package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs +0 -6
  25. package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs.map +1 -1
  26. package/dist/lib/adapters/oauth-passthrough-resolver.mjs +0 -6
  27. package/dist/lib/adapters/oauth-passthrough-resolver.mjs.map +1 -1
  28. package/dist/lib/adapters/property-list-adapter.mjs +0 -6
  29. package/dist/lib/adapters/property-list-adapter.mjs.map +1 -1
  30. package/dist/lib/adapters/roster-account-store.mjs +0 -6
  31. package/dist/lib/adapters/roster-account-store.mjs.map +1 -1
  32. package/dist/lib/adapters/si-session-manager.mjs +0 -6
  33. package/dist/lib/adapters/si-session-manager.mjs.map +1 -1
  34. package/dist/lib/adapters/version/3.0/brand-fields.mjs +0 -6
  35. package/dist/lib/adapters/version/3.0/brand-fields.mjs.map +1 -1
  36. package/dist/lib/adapters/version/3.0/get-products.mjs +0 -6
  37. package/dist/lib/adapters/version/3.0/get-products.mjs.map +1 -1
  38. package/dist/lib/adapters/version/3.0/index.mjs +0 -6
  39. package/dist/lib/adapters/version/3.0/index.mjs.map +1 -1
  40. package/dist/lib/adapters/version/3.0/sync-accounts.mjs +0 -6
  41. package/dist/lib/adapters/version/3.0/sync-accounts.mjs.map +1 -1
  42. package/dist/lib/adapters/version/index.mjs +0 -6
  43. package/dist/lib/adapters/version/index.mjs.map +1 -1
  44. package/dist/lib/adapters/version/types.mjs +0 -6
  45. package/dist/lib/advanced.mjs +0 -6
  46. package/dist/lib/advanced.mjs.map +1 -1
  47. package/dist/lib/agents/index.generated.mjs +0 -6
  48. package/dist/lib/agents/index.generated.mjs.map +1 -1
  49. package/dist/lib/auth/index.mjs +0 -6
  50. package/dist/lib/auth/index.mjs.map +1 -1
  51. package/dist/lib/auth/oauth/CLIFlowHandler.mjs +0 -6
  52. package/dist/lib/auth/oauth/CLIFlowHandler.mjs.map +1 -1
  53. package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs +0 -6
  54. package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs.map +1 -1
  55. package/dist/lib/auth/oauth/MCPOAuthProvider.mjs +0 -6
  56. package/dist/lib/auth/oauth/MCPOAuthProvider.mjs.map +1 -1
  57. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs +0 -6
  58. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs.map +1 -1
  59. package/dist/lib/auth/oauth/authorization-required.mjs +0 -6
  60. package/dist/lib/auth/oauth/authorization-required.mjs.map +1 -1
  61. package/dist/lib/auth/oauth/diagnose.mjs +0 -6
  62. package/dist/lib/auth/oauth/diagnose.mjs.map +1 -1
  63. package/dist/lib/auth/oauth/diagnostics.mjs +0 -6
  64. package/dist/lib/auth/oauth/diagnostics.mjs.map +1 -1
  65. package/dist/lib/auth/oauth/discovery.mjs +0 -6
  66. package/dist/lib/auth/oauth/discovery.mjs.map +1 -1
  67. package/dist/lib/auth/oauth/file-storage.mjs +0 -6
  68. package/dist/lib/auth/oauth/file-storage.mjs.map +1 -1
  69. package/dist/lib/auth/oauth/index.mjs +0 -6
  70. package/dist/lib/auth/oauth/index.mjs.map +1 -1
  71. package/dist/lib/auth/oauth/secret-resolver.mjs +0 -6
  72. package/dist/lib/auth/oauth/secret-resolver.mjs.map +1 -1
  73. package/dist/lib/auth/oauth/storage-registry.mjs +0 -6
  74. package/dist/lib/auth/oauth/storage-registry.mjs.map +1 -1
  75. package/dist/lib/auth/oauth/types.mjs +0 -6
  76. package/dist/lib/auth/oauth/types.mjs.map +1 -1
  77. package/dist/lib/auth/oauth/web-flow.mjs +0 -6
  78. package/dist/lib/auth/oauth/web-flow.mjs.map +1 -1
  79. package/dist/lib/brand/index.mjs +0 -6
  80. package/dist/lib/brand/index.mjs.map +1 -1
  81. package/dist/lib/canonical-references/index.mjs +6 -7
  82. package/dist/lib/canonical-references/index.mjs.map +1 -1
  83. package/dist/lib/client/index.mjs +0 -6
  84. package/dist/lib/client/index.mjs.map +1 -1
  85. package/dist/lib/compliance/index.mjs +0 -6
  86. package/dist/lib/compliance/index.mjs.map +1 -1
  87. package/dist/lib/compliance-fixtures/index.mjs +0 -6
  88. package/dist/lib/compliance-fixtures/index.mjs.map +1 -1
  89. package/dist/lib/compliance-fixtures/test-authorization-server.mjs +0 -6
  90. package/dist/lib/compliance-fixtures/test-authorization-server.mjs.map +1 -1
  91. package/dist/lib/conformance/index.mjs +0 -6
  92. package/dist/lib/conformance/index.mjs.map +1 -1
  93. package/dist/lib/conformance/invariants/uniformError.mjs +0 -6
  94. package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
  95. package/dist/lib/conformance/invariants/uniformErrorComparator.mjs +0 -6
  96. package/dist/lib/conformance/invariants/uniformErrorComparator.mjs.map +1 -1
  97. package/dist/lib/conformance/oracle.mjs +0 -6
  98. package/dist/lib/conformance/oracle.mjs.map +1 -1
  99. package/dist/lib/conformance/runConformance.mjs +0 -6
  100. package/dist/lib/conformance/runConformance.mjs.map +1 -1
  101. package/dist/lib/conformance/runners.mjs +0 -6
  102. package/dist/lib/conformance/runners.mjs.map +1 -1
  103. package/dist/lib/conformance/schemaArbitrary.mjs +0 -6
  104. package/dist/lib/conformance/schemaArbitrary.mjs.map +1 -1
  105. package/dist/lib/conformance/schemaLoader.mjs +5 -6
  106. package/dist/lib/conformance/schemaLoader.mjs.map +1 -1
  107. package/dist/lib/conformance/seeder.mjs +0 -6
  108. package/dist/lib/conformance/seeder.mjs.map +1 -1
  109. package/dist/lib/conformance/types.mjs +0 -6
  110. package/dist/lib/conformance/types.mjs.map +1 -1
  111. package/dist/lib/conformance/webhook.mjs +0 -6
  112. package/dist/lib/conformance/webhook.mjs.map +1 -1
  113. package/dist/lib/core/ADCPMultiAgentClient.mjs +0 -6
  114. package/dist/lib/core/ADCPMultiAgentClient.mjs.map +1 -1
  115. package/dist/lib/core/AgentClient.mjs +0 -6
  116. package/dist/lib/core/AgentClient.mjs.map +1 -1
  117. package/dist/lib/core/AsyncHandler.mjs +0 -6
  118. package/dist/lib/core/AsyncHandler.mjs.map +1 -1
  119. package/dist/lib/core/ConfigurationManager.mjs +0 -6
  120. package/dist/lib/core/ConfigurationManager.mjs.map +1 -1
  121. package/dist/lib/core/ConversationTypes.mjs +0 -6
  122. package/dist/lib/core/CreativeAgentClient.mjs +0 -6
  123. package/dist/lib/core/CreativeAgentClient.mjs.map +1 -1
  124. package/dist/lib/core/GovernanceMiddleware.mjs +0 -6
  125. package/dist/lib/core/GovernanceMiddleware.mjs.map +1 -1
  126. package/dist/lib/core/GovernanceTypes.mjs +0 -6
  127. package/dist/lib/core/GovernanceTypes.mjs.map +1 -1
  128. package/dist/lib/core/ProtocolResponseParser.mjs +0 -6
  129. package/dist/lib/core/ProtocolResponseParser.mjs.map +1 -1
  130. package/dist/lib/core/ResponseValidator.mjs +0 -6
  131. package/dist/lib/core/ResponseValidator.mjs.map +1 -1
  132. package/dist/lib/core/SingleAgentClient.mjs +0 -6
  133. package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
  134. package/dist/lib/core/TaskEventTypes.mjs +0 -6
  135. package/dist/lib/core/TaskEventTypes.mjs.map +1 -1
  136. package/dist/lib/core/TaskExecutor.mjs +0 -6
  137. package/dist/lib/core/TaskExecutor.mjs.map +1 -1
  138. package/dist/lib/core/match.mjs +0 -6
  139. package/dist/lib/core/match.mjs.map +1 -1
  140. package/dist/lib/core/task-status.mjs +0 -6
  141. package/dist/lib/core/task-status.mjs.map +1 -1
  142. package/dist/lib/core/webhook-url.mjs +0 -6
  143. package/dist/lib/core/webhook-url.mjs.map +1 -1
  144. package/dist/lib/discovery/adagents-redirects.mjs +0 -6
  145. package/dist/lib/discovery/adagents-redirects.mjs.map +1 -1
  146. package/dist/lib/discovery/agent-directory.mjs +0 -6
  147. package/dist/lib/discovery/agent-directory.mjs.map +1 -1
  148. package/dist/lib/discovery/inline-publisher-properties.mjs +0 -6
  149. package/dist/lib/discovery/inline-publisher-properties.mjs.map +1 -1
  150. package/dist/lib/discovery/network-consistency-checker.mjs +0 -6
  151. package/dist/lib/discovery/network-consistency-checker.mjs.map +1 -1
  152. package/dist/lib/discovery/property-crawler.mjs +0 -6
  153. package/dist/lib/discovery/property-crawler.mjs.map +1 -1
  154. package/dist/lib/discovery/property-index.mjs +0 -6
  155. package/dist/lib/discovery/property-index.mjs.map +1 -1
  156. package/dist/lib/discovery/publisher-property-selector.mjs +0 -6
  157. package/dist/lib/discovery/publisher-property-selector.mjs.map +1 -1
  158. package/dist/lib/discovery/resolve-agent-properties.mjs +0 -6
  159. package/dist/lib/discovery/resolve-agent-properties.mjs.map +1 -1
  160. package/dist/lib/discovery/types.mjs +0 -6
  161. package/dist/lib/discovery/validate-adagents.mjs +0 -6
  162. package/dist/lib/discovery/validate-adagents.mjs.map +1 -1
  163. package/dist/lib/enums.mjs +0 -6
  164. package/dist/lib/enums.mjs.map +1 -1
  165. package/dist/lib/errors/index.mjs +0 -6
  166. package/dist/lib/errors/index.mjs.map +1 -1
  167. package/dist/lib/express-mcp/index.mjs +0 -6
  168. package/dist/lib/express-mcp/index.mjs.map +1 -1
  169. package/dist/lib/governance/index.mjs +0 -6
  170. package/dist/lib/governance/index.mjs.map +1 -1
  171. package/dist/lib/handlers/types.mjs +0 -6
  172. package/dist/lib/handlers/types.mjs.map +1 -1
  173. package/dist/lib/index.mjs +0 -6
  174. package/dist/lib/index.mjs.map +1 -1
  175. package/dist/lib/media-buy/available-actions.mjs +0 -6
  176. package/dist/lib/media-buy/available-actions.mjs.map +1 -1
  177. package/dist/lib/media-buy/index.mjs +0 -6
  178. package/dist/lib/media-buy/index.mjs.map +1 -1
  179. package/dist/lib/media-buy/preflight.mjs +0 -6
  180. package/dist/lib/media-buy/preflight.mjs.map +1 -1
  181. package/dist/lib/media-buy/property-policy.mjs +0 -6
  182. package/dist/lib/media-buy/property-policy.mjs.map +1 -1
  183. package/dist/lib/media-buy/types.mjs +0 -6
  184. package/dist/lib/media-buy/types.mjs.map +1 -1
  185. package/dist/lib/media-buy/update-fields.generated.mjs +0 -6
  186. package/dist/lib/media-buy/update-fields.generated.mjs.map +1 -1
  187. package/dist/lib/mock-server/creative-ad-server/seed-data.mjs +0 -6
  188. package/dist/lib/mock-server/creative-ad-server/seed-data.mjs.map +1 -1
  189. package/dist/lib/mock-server/creative-ad-server/server.mjs +0 -6
  190. package/dist/lib/mock-server/creative-ad-server/server.mjs.map +1 -1
  191. package/dist/lib/mock-server/creative-template/seed-data.mjs +0 -6
  192. package/dist/lib/mock-server/creative-template/seed-data.mjs.map +1 -1
  193. package/dist/lib/mock-server/creative-template/server.mjs +0 -6
  194. package/dist/lib/mock-server/creative-template/server.mjs.map +1 -1
  195. package/dist/lib/mock-server/index.mjs +0 -6
  196. package/dist/lib/mock-server/index.mjs.map +1 -1
  197. package/dist/lib/mock-server/sales-guaranteed/recipe.mjs +0 -6
  198. package/dist/lib/mock-server/sales-guaranteed/recipe.mjs.map +1 -1
  199. package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs +0 -6
  200. package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs.map +1 -1
  201. package/dist/lib/mock-server/sales-guaranteed/server.mjs +0 -6
  202. package/dist/lib/mock-server/sales-guaranteed/server.mjs.map +1 -1
  203. package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs +0 -6
  204. package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs.map +1 -1
  205. package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs +0 -6
  206. package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs.map +1 -1
  207. package/dist/lib/mock-server/sales-non-guaranteed/server.mjs +0 -6
  208. package/dist/lib/mock-server/sales-non-guaranteed/server.mjs.map +1 -1
  209. package/dist/lib/mock-server/sales-social/seed-data.mjs +0 -6
  210. package/dist/lib/mock-server/sales-social/seed-data.mjs.map +1 -1
  211. package/dist/lib/mock-server/sales-social/server.mjs +0 -6
  212. package/dist/lib/mock-server/sales-social/server.mjs.map +1 -1
  213. package/dist/lib/mock-server/scenario.mjs +0 -6
  214. package/dist/lib/mock-server/scenario.mjs.map +1 -1
  215. package/dist/lib/mock-server/signal-marketplace/seed-data.mjs +0 -6
  216. package/dist/lib/mock-server/signal-marketplace/seed-data.mjs.map +1 -1
  217. package/dist/lib/mock-server/signal-marketplace/server.mjs +0 -6
  218. package/dist/lib/mock-server/signal-marketplace/server.mjs.map +1 -1
  219. package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs +0 -6
  220. package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs.map +1 -1
  221. package/dist/lib/mock-server/sponsored-intelligence/server.mjs +0 -6
  222. package/dist/lib/mock-server/sponsored-intelligence/server.mjs.map +1 -1
  223. package/dist/lib/net/address-guards.mjs +0 -6
  224. package/dist/lib/net/address-guards.mjs.map +1 -1
  225. package/dist/lib/net/index.mjs +0 -6
  226. package/dist/lib/net/index.mjs.map +1 -1
  227. package/dist/lib/net/ssrf-fetch.mjs +0 -6
  228. package/dist/lib/net/ssrf-fetch.mjs.map +1 -1
  229. package/dist/lib/observability/index.mjs +0 -6
  230. package/dist/lib/observability/index.mjs.map +1 -1
  231. package/dist/lib/observability/tracing.mjs +6 -7
  232. package/dist/lib/observability/tracing.mjs.map +1 -1
  233. package/dist/lib/protocols/a2a.mjs +0 -6
  234. package/dist/lib/protocols/a2a.mjs.map +1 -1
  235. package/dist/lib/protocols/abort.mjs +0 -6
  236. package/dist/lib/protocols/abort.mjs.map +1 -1
  237. package/dist/lib/protocols/index.mjs +0 -6
  238. package/dist/lib/protocols/index.mjs.map +1 -1
  239. package/dist/lib/protocols/mcp-modern.mjs +0 -6
  240. package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
  241. package/dist/lib/protocols/mcp-tasks.mjs +0 -6
  242. package/dist/lib/protocols/mcp-tasks.mjs.map +1 -1
  243. package/dist/lib/protocols/mcp.mjs +0 -6
  244. package/dist/lib/protocols/mcp.mjs.map +1 -1
  245. package/dist/lib/protocols/rawResponseCapture.mjs +0 -6
  246. package/dist/lib/protocols/rawResponseCapture.mjs.map +1 -1
  247. package/dist/lib/protocols/responseSizeLimit.mjs +0 -6
  248. package/dist/lib/protocols/responseSizeLimit.mjs.map +1 -1
  249. package/dist/lib/protocols/transportDiagnostics.mjs +0 -6
  250. package/dist/lib/protocols/transportDiagnostics.mjs.map +1 -1
  251. package/dist/lib/registry/cursor-store.mjs +0 -6
  252. package/dist/lib/registry/cursor-store.mjs.map +1 -1
  253. package/dist/lib/registry/feed-stream.mjs +0 -6
  254. package/dist/lib/registry/feed-stream.mjs.map +1 -1
  255. package/dist/lib/registry/index.mjs +0 -6
  256. package/dist/lib/registry/index.mjs.map +1 -1
  257. package/dist/lib/registry/property-registry.mjs +0 -6
  258. package/dist/lib/registry/property-registry.mjs.map +1 -1
  259. package/dist/lib/registry/sync.mjs +0 -6
  260. package/dist/lib/registry/sync.mjs.map +1 -1
  261. package/dist/lib/registry/types.generated.mjs +0 -6
  262. package/dist/lib/registry/types.mjs +0 -6
  263. package/dist/lib/schemas/index.mjs +0 -6
  264. package/dist/lib/schemas/index.mjs.map +1 -1
  265. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  266. package/dist/lib/server/a2a-adapter.mjs +0 -6
  267. package/dist/lib/server/a2a-adapter.mjs.map +1 -1
  268. package/dist/lib/server/account-mode.mjs +0 -6
  269. package/dist/lib/server/account-mode.mjs.map +1 -1
  270. package/dist/lib/server/adcp-server.mjs +0 -6
  271. package/dist/lib/server/adcp-server.mjs.map +1 -1
  272. package/dist/lib/server/auth-introspection.mjs +0 -6
  273. package/dist/lib/server/auth-introspection.mjs.map +1 -1
  274. package/dist/lib/server/auth-signature.mjs +0 -6
  275. package/dist/lib/server/auth-signature.mjs.map +1 -1
  276. package/dist/lib/server/auth.mjs +0 -6
  277. package/dist/lib/server/auth.mjs.map +1 -1
  278. package/dist/lib/server/create-adcp-server.mjs +0 -6
  279. package/dist/lib/server/create-adcp-server.mjs.map +1 -1
  280. package/dist/lib/server/credential-policy.mjs +0 -6
  281. package/dist/lib/server/credential-policy.mjs.map +1 -1
  282. package/dist/lib/server/ctx-metadata/backends/memory.mjs +0 -6
  283. package/dist/lib/server/ctx-metadata/backends/memory.mjs.map +1 -1
  284. package/dist/lib/server/ctx-metadata/backends/pg.mjs +0 -6
  285. package/dist/lib/server/ctx-metadata/backends/pg.mjs.map +1 -1
  286. package/dist/lib/server/ctx-metadata/backends/redis.mjs +0 -6
  287. package/dist/lib/server/ctx-metadata/backends/redis.mjs.map +1 -1
  288. package/dist/lib/server/ctx-metadata/index.mjs +0 -6
  289. package/dist/lib/server/ctx-metadata/index.mjs.map +1 -1
  290. package/dist/lib/server/ctx-metadata/store.mjs +0 -6
  291. package/dist/lib/server/ctx-metadata/store.mjs.map +1 -1
  292. package/dist/lib/server/ctx-metadata/wire-shape.mjs +0 -6
  293. package/dist/lib/server/ctx-metadata/wire-shape.mjs.map +1 -1
  294. package/dist/lib/server/decisioning/account.mjs +0 -6
  295. package/dist/lib/server/decisioning/account.mjs.map +1 -1
  296. package/dist/lib/server/decisioning/admin-router.mjs +0 -6
  297. package/dist/lib/server/decisioning/admin-router.mjs.map +1 -1
  298. package/dist/lib/server/decisioning/assembly-helpers.mjs +0 -6
  299. package/dist/lib/server/decisioning/assembly-helpers.mjs.map +1 -1
  300. package/dist/lib/server/decisioning/async-outcome.mjs +0 -6
  301. package/dist/lib/server/decisioning/async-outcome.mjs.map +1 -1
  302. package/dist/lib/server/decisioning/buyer-agent.mjs +0 -6
  303. package/dist/lib/server/decisioning/buyer-agent.mjs.map +1 -1
  304. package/dist/lib/server/decisioning/capabilities.mjs +0 -6
  305. package/dist/lib/server/decisioning/capabilities.mjs.map +1 -1
  306. package/dist/lib/server/decisioning/compose.mjs +0 -6
  307. package/dist/lib/server/decisioning/compose.mjs.map +1 -1
  308. package/dist/lib/server/decisioning/context.mjs +0 -6
  309. package/dist/lib/server/decisioning/errors-typed.mjs +0 -6
  310. package/dist/lib/server/decisioning/errors-typed.mjs.map +1 -1
  311. package/dist/lib/server/decisioning/helpers.mjs +0 -6
  312. package/dist/lib/server/decisioning/helpers.mjs.map +1 -1
  313. package/dist/lib/server/decisioning/index.mjs +0 -6
  314. package/dist/lib/server/decisioning/index.mjs.map +1 -1
  315. package/dist/lib/server/decisioning/list-helpers.mjs +0 -6
  316. package/dist/lib/server/decisioning/list-helpers.mjs.map +1 -1
  317. package/dist/lib/server/decisioning/manifest-helpers.mjs +0 -6
  318. package/dist/lib/server/decisioning/manifest-helpers.mjs.map +1 -1
  319. package/dist/lib/server/decisioning/pagination.mjs +0 -6
  320. package/dist/lib/server/decisioning/platform-helpers.mjs +0 -6
  321. package/dist/lib/server/decisioning/platform-helpers.mjs.map +1 -1
  322. package/dist/lib/server/decisioning/platform.mjs +0 -6
  323. package/dist/lib/server/decisioning/proposal/dispatch.mjs +0 -6
  324. package/dist/lib/server/decisioning/proposal/dispatch.mjs.map +1 -1
  325. package/dist/lib/server/decisioning/proposal/index.mjs +0 -6
  326. package/dist/lib/server/decisioning/proposal/index.mjs.map +1 -1
  327. package/dist/lib/server/decisioning/proposal/lifecycle.mjs +0 -6
  328. package/dist/lib/server/decisioning/proposal/lifecycle.mjs.map +1 -1
  329. package/dist/lib/server/decisioning/proposal/mock-manager.mjs +0 -6
  330. package/dist/lib/server/decisioning/proposal/mock-manager.mjs.map +1 -1
  331. package/dist/lib/server/decisioning/proposal/store.mjs +0 -6
  332. package/dist/lib/server/decisioning/proposal/store.mjs.map +1 -1
  333. package/dist/lib/server/decisioning/proposal/types.mjs +0 -6
  334. package/dist/lib/server/decisioning/proposal/types.mjs.map +1 -1
  335. package/dist/lib/server/decisioning/resolve-presets.mjs +0 -6
  336. package/dist/lib/server/decisioning/resolve-presets.mjs.map +1 -1
  337. package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs +0 -6
  338. package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs.map +1 -1
  339. package/dist/lib/server/decisioning/runtime/from-platform.mjs +0 -6
  340. package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
  341. package/dist/lib/server/decisioning/runtime/observed-modes.mjs +0 -6
  342. package/dist/lib/server/decisioning/runtime/observed-modes.mjs.map +1 -1
  343. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +0 -6
  344. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs.map +1 -1
  345. package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs +0 -6
  346. package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs.map +1 -1
  347. package/dist/lib/server/decisioning/runtime/task-registry.mjs +0 -6
  348. package/dist/lib/server/decisioning/runtime/task-registry.mjs.map +1 -1
  349. package/dist/lib/server/decisioning/runtime/to-context.mjs +0 -6
  350. package/dist/lib/server/decisioning/runtime/to-context.mjs.map +1 -1
  351. package/dist/lib/server/decisioning/runtime/validate-platform.mjs +0 -6
  352. package/dist/lib/server/decisioning/runtime/validate-platform.mjs.map +1 -1
  353. package/dist/lib/server/decisioning/specialisms/audiences.mjs +0 -6
  354. package/dist/lib/server/decisioning/specialisms/brand-rights.mjs +0 -6
  355. package/dist/lib/server/decisioning/specialisms/campaign-governance.mjs +0 -6
  356. package/dist/lib/server/decisioning/specialisms/content-standards.mjs +0 -6
  357. package/dist/lib/server/decisioning/specialisms/creative-ad-server.mjs +0 -6
  358. package/dist/lib/server/decisioning/specialisms/creative.mjs +0 -6
  359. package/dist/lib/server/decisioning/specialisms/lists.mjs +0 -6
  360. package/dist/lib/server/decisioning/specialisms/sales.mjs +0 -6
  361. package/dist/lib/server/decisioning/specialisms/signals.mjs +0 -6
  362. package/dist/lib/server/decisioning/specialisms/sponsored-intelligence.mjs +0 -6
  363. package/dist/lib/server/decisioning/start-time.mjs +0 -6
  364. package/dist/lib/server/decisioning/start-time.mjs.map +1 -1
  365. package/dist/lib/server/decisioning/status-changes.mjs +0 -6
  366. package/dist/lib/server/decisioning/status-changes.mjs.map +1 -1
  367. package/dist/lib/server/decisioning/status-mappers.mjs +0 -6
  368. package/dist/lib/server/decisioning/status-mappers.mjs.map +1 -1
  369. package/dist/lib/server/decisioning/tenant-registry.mjs +0 -6
  370. package/dist/lib/server/decisioning/tenant-registry.mjs.map +1 -1
  371. package/dist/lib/server/decisioning/tenant-store.mjs +0 -6
  372. package/dist/lib/server/decisioning/tenant-store.mjs.map +1 -1
  373. package/dist/lib/server/decisioning/validate-specialisms.mjs +0 -6
  374. package/dist/lib/server/decisioning/validate-specialisms.mjs.map +1 -1
  375. package/dist/lib/server/dynamic-registry.mjs +0 -6
  376. package/dist/lib/server/dynamic-registry.mjs.map +1 -1
  377. package/dist/lib/server/envelope-allowlist.mjs +0 -6
  378. package/dist/lib/server/envelope-allowlist.mjs.map +1 -1
  379. package/dist/lib/server/error-arm-tools.mjs +5 -6
  380. package/dist/lib/server/error-arm-tools.mjs.map +1 -1
  381. package/dist/lib/server/errors.mjs +0 -6
  382. package/dist/lib/server/errors.mjs.map +1 -1
  383. package/dist/lib/server/example-tld-guard.mjs +0 -6
  384. package/dist/lib/server/example-tld-guard.mjs.map +1 -1
  385. package/dist/lib/server/express-adapter.mjs +0 -6
  386. package/dist/lib/server/express-adapter.mjs.map +1 -1
  387. package/dist/lib/server/governance.mjs +0 -6
  388. package/dist/lib/server/governance.mjs.map +1 -1
  389. package/dist/lib/server/idempotency/backends/lazy.mjs +0 -6
  390. package/dist/lib/server/idempotency/backends/lazy.mjs.map +1 -1
  391. package/dist/lib/server/idempotency/backends/memory.mjs +0 -6
  392. package/dist/lib/server/idempotency/backends/memory.mjs.map +1 -1
  393. package/dist/lib/server/idempotency/backends/pg.mjs +0 -6
  394. package/dist/lib/server/idempotency/backends/pg.mjs.map +1 -1
  395. package/dist/lib/server/idempotency/backends/redis.mjs +0 -6
  396. package/dist/lib/server/idempotency/backends/redis.mjs.map +1 -1
  397. package/dist/lib/server/idempotency/index.mjs +0 -6
  398. package/dist/lib/server/idempotency/index.mjs.map +1 -1
  399. package/dist/lib/server/idempotency/store.mjs +0 -6
  400. package/dist/lib/server/idempotency/store.mjs.map +1 -1
  401. package/dist/lib/server/index.mjs +0 -6
  402. package/dist/lib/server/index.mjs.map +1 -1
  403. package/dist/lib/server/legacy/v5/index.mjs +0 -6
  404. package/dist/lib/server/legacy/v5/index.mjs.map +1 -1
  405. package/dist/lib/server/mcp-modern-server.mjs +0 -6
  406. package/dist/lib/server/mcp-modern-server.mjs.map +1 -1
  407. package/dist/lib/server/media-buy-actions.mjs +0 -6
  408. package/dist/lib/server/media-buy-actions.mjs.map +1 -1
  409. package/dist/lib/server/media-buy-helpers.mjs +0 -6
  410. package/dist/lib/server/media-buy-helpers.mjs.map +1 -1
  411. package/dist/lib/server/media-buy-store.mjs +0 -6
  412. package/dist/lib/server/media-buy-store.mjs.map +1 -1
  413. package/dist/lib/server/normalize-errors.mjs +0 -6
  414. package/dist/lib/server/normalize-errors.mjs.map +1 -1
  415. package/dist/lib/server/operational-platform.mjs +0 -6
  416. package/dist/lib/server/operational-platform.mjs.map +1 -1
  417. package/dist/lib/server/pick-safe-details.mjs +0 -6
  418. package/dist/lib/server/pick-safe-details.mjs.map +1 -1
  419. package/dist/lib/server/pin-and-bind-fetch.mjs +0 -6
  420. package/dist/lib/server/pin-and-bind-fetch.mjs.map +1 -1
  421. package/dist/lib/server/postgres-state-store.mjs +0 -6
  422. package/dist/lib/server/postgres-state-store.mjs.map +1 -1
  423. package/dist/lib/server/postgres-task-store.mjs +0 -6
  424. package/dist/lib/server/postgres-task-store.mjs.map +1 -1
  425. package/dist/lib/server/product-defaults.mjs +0 -6
  426. package/dist/lib/server/product-defaults.mjs.map +1 -1
  427. package/dist/lib/server/redact.mjs +0 -6
  428. package/dist/lib/server/redact.mjs.map +1 -1
  429. package/dist/lib/server/responses.mjs +0 -6
  430. package/dist/lib/server/responses.mjs.map +1 -1
  431. package/dist/lib/server/serve.mjs +0 -6
  432. package/dist/lib/server/serve.mjs.map +1 -1
  433. package/dist/lib/server/socket-mode/conformance-client.mjs +0 -6
  434. package/dist/lib/server/socket-mode/conformance-client.mjs.map +1 -1
  435. package/dist/lib/server/socket-mode/index.mjs +0 -6
  436. package/dist/lib/server/socket-mode/index.mjs.map +1 -1
  437. package/dist/lib/server/socket-mode/ws-transport.mjs +0 -6
  438. package/dist/lib/server/socket-mode/ws-transport.mjs.map +1 -1
  439. package/dist/lib/server/state-machine.mjs +0 -6
  440. package/dist/lib/server/state-machine.mjs.map +1 -1
  441. package/dist/lib/server/state-store.mjs +0 -6
  442. package/dist/lib/server/state-store.mjs.map +1 -1
  443. package/dist/lib/server/structured-serialize.mjs +0 -6
  444. package/dist/lib/server/structured-serialize.mjs.map +1 -1
  445. package/dist/lib/server/targeting-helpers.mjs +0 -6
  446. package/dist/lib/server/targeting-helpers.mjs.map +1 -1
  447. package/dist/lib/server/tasks.mjs +0 -6
  448. package/dist/lib/server/tasks.mjs.map +1 -1
  449. package/dist/lib/server/test-controller-bridge.mjs +0 -6
  450. package/dist/lib/server/test-controller-bridge.mjs.map +1 -1
  451. package/dist/lib/server/test-controller.mjs +0 -6
  452. package/dist/lib/server/test-controller.mjs.map +1 -1
  453. package/dist/lib/server/upstream-helpers.mjs +0 -6
  454. package/dist/lib/server/upstream-helpers.mjs.map +1 -1
  455. package/dist/lib/server/webhook-emitter.mjs +0 -6
  456. package/dist/lib/server/webhook-emitter.mjs.map +1 -1
  457. package/dist/lib/server/wire-safe.mjs +0 -6
  458. package/dist/lib/server/wire-safe.mjs.map +1 -1
  459. package/dist/lib/server/wire-spec-fields.generated.mjs +0 -6
  460. package/dist/lib/server/wire-spec-fields.generated.mjs.map +1 -1
  461. package/dist/lib/server/wrap-envelope.mjs +0 -6
  462. package/dist/lib/server/wrap-envelope.mjs.map +1 -1
  463. package/dist/lib/signing/agent-context.mjs +0 -6
  464. package/dist/lib/signing/agent-context.mjs.map +1 -1
  465. package/dist/lib/signing/agent-fetch.mjs +0 -6
  466. package/dist/lib/signing/agent-fetch.mjs.map +1 -1
  467. package/dist/lib/signing/agent-resolver/canonicalize.mjs +0 -6
  468. package/dist/lib/signing/agent-resolver/canonicalize.mjs.map +1 -1
  469. package/dist/lib/signing/agent-resolver/capabilities-types.mjs +0 -6
  470. package/dist/lib/signing/agent-resolver/capabilities-types.mjs.map +1 -1
  471. package/dist/lib/signing/agent-resolver/consistency.mjs +0 -6
  472. package/dist/lib/signing/agent-resolver/consistency.mjs.map +1 -1
  473. package/dist/lib/signing/agent-resolver/errors.mjs +0 -6
  474. package/dist/lib/signing/agent-resolver/errors.mjs.map +1 -1
  475. package/dist/lib/signing/agent-resolver/etld.mjs +0 -6
  476. package/dist/lib/signing/agent-resolver/etld.mjs.map +1 -1
  477. package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +0 -6
  478. package/dist/lib/signing/agent-resolver/fetch-helpers.mjs.map +1 -1
  479. package/dist/lib/signing/agent-resolver/index.mjs +0 -6
  480. package/dist/lib/signing/agent-resolver/index.mjs.map +1 -1
  481. package/dist/lib/signing/agent-resolver/jwks-set.mjs +0 -6
  482. package/dist/lib/signing/agent-resolver/jwks-set.mjs.map +1 -1
  483. package/dist/lib/signing/agent-resolver/resolve-agent.mjs +0 -6
  484. package/dist/lib/signing/agent-resolver/resolve-agent.mjs.map +1 -1
  485. package/dist/lib/signing/agent-resolver/select-agent.mjs +0 -6
  486. package/dist/lib/signing/agent-resolver/select-agent.mjs.map +1 -1
  487. package/dist/lib/signing/agent-resolver/strict-json.mjs +0 -6
  488. package/dist/lib/signing/agent-resolver/strict-json.mjs.map +1 -1
  489. package/dist/lib/signing/brand-jwks.mjs +0 -6
  490. package/dist/lib/signing/brand-jwks.mjs.map +1 -1
  491. package/dist/lib/signing/canonicalize.mjs +0 -6
  492. package/dist/lib/signing/canonicalize.mjs.map +1 -1
  493. package/dist/lib/signing/capability-cache.mjs +0 -6
  494. package/dist/lib/signing/capability-cache.mjs.map +1 -1
  495. package/dist/lib/signing/capability-priming.mjs +0 -6
  496. package/dist/lib/signing/capability-priming.mjs.map +1 -1
  497. package/dist/lib/signing/client.mjs +0 -6
  498. package/dist/lib/signing/client.mjs.map +1 -1
  499. package/dist/lib/signing/content-digest.mjs +0 -6
  500. package/dist/lib/signing/content-digest.mjs.map +1 -1
  501. package/dist/lib/signing/crypto.mjs +0 -6
  502. package/dist/lib/signing/crypto.mjs.map +1 -1
  503. package/dist/lib/signing/ecdsa-encoding.mjs +0 -6
  504. package/dist/lib/signing/ecdsa-encoding.mjs.map +1 -1
  505. package/dist/lib/signing/errors.mjs +0 -6
  506. package/dist/lib/signing/errors.mjs.map +1 -1
  507. package/dist/lib/signing/fetch-async.mjs +0 -6
  508. package/dist/lib/signing/fetch-async.mjs.map +1 -1
  509. package/dist/lib/signing/fetch.mjs +0 -6
  510. package/dist/lib/signing/fetch.mjs.map +1 -1
  511. package/dist/lib/signing/index.mjs +0 -6
  512. package/dist/lib/signing/index.mjs.map +1 -1
  513. package/dist/lib/signing/jwks-helpers.mjs +0 -6
  514. package/dist/lib/signing/jwks-helpers.mjs.map +1 -1
  515. package/dist/lib/signing/jwks-https.mjs +0 -6
  516. package/dist/lib/signing/jwks-https.mjs.map +1 -1
  517. package/dist/lib/signing/jwks.mjs +0 -6
  518. package/dist/lib/signing/jwks.mjs.map +1 -1
  519. package/dist/lib/signing/middleware.mjs +0 -6
  520. package/dist/lib/signing/middleware.mjs.map +1 -1
  521. package/dist/lib/signing/parser.mjs +0 -6
  522. package/dist/lib/signing/parser.mjs.map +1 -1
  523. package/dist/lib/signing/postgres-replay-store.mjs +0 -6
  524. package/dist/lib/signing/postgres-replay-store.mjs.map +1 -1
  525. package/dist/lib/signing/protocol-response.mjs +0 -6
  526. package/dist/lib/signing/protocol-response.mjs.map +1 -1
  527. package/dist/lib/signing/provider.mjs +0 -6
  528. package/dist/lib/signing/redis-replay-store.mjs +0 -6
  529. package/dist/lib/signing/redis-replay-store.mjs.map +1 -1
  530. package/dist/lib/signing/replay.mjs +0 -6
  531. package/dist/lib/signing/replay.mjs.map +1 -1
  532. package/dist/lib/signing/request-context.mjs +0 -6
  533. package/dist/lib/signing/request-context.mjs.map +1 -1
  534. package/dist/lib/signing/revocation-https.mjs +0 -6
  535. package/dist/lib/signing/revocation-https.mjs.map +1 -1
  536. package/dist/lib/signing/revocation.mjs +0 -6
  537. package/dist/lib/signing/revocation.mjs.map +1 -1
  538. package/dist/lib/signing/server.mjs +0 -6
  539. package/dist/lib/signing/server.mjs.map +1 -1
  540. package/dist/lib/signing/signer-async.mjs +0 -6
  541. package/dist/lib/signing/signer-async.mjs.map +1 -1
  542. package/dist/lib/signing/signer.mjs +0 -6
  543. package/dist/lib/signing/signer.mjs.map +1 -1
  544. package/dist/lib/signing/testing.mjs +0 -6
  545. package/dist/lib/signing/testing.mjs.map +1 -1
  546. package/dist/lib/signing/types.mjs +0 -6
  547. package/dist/lib/signing/types.mjs.map +1 -1
  548. package/dist/lib/signing/verifier.mjs +0 -6
  549. package/dist/lib/signing/verifier.mjs.map +1 -1
  550. package/dist/lib/signing/webhook-auth-detection.mjs +0 -6
  551. package/dist/lib/signing/webhook-auth-detection.mjs.map +1 -1
  552. package/dist/lib/signing/webhook-verifier.mjs +0 -6
  553. package/dist/lib/signing/webhook-verifier.mjs.map +1 -1
  554. package/dist/lib/storage/MemoryStorage.mjs +0 -6
  555. package/dist/lib/storage/MemoryStorage.mjs.map +1 -1
  556. package/dist/lib/storage/interfaces.mjs +0 -6
  557. package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs +0 -6
  558. package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs.map +1 -1
  559. package/dist/lib/substitution/encoder/index.mjs +0 -6
  560. package/dist/lib/substitution/encoder/index.mjs.map +1 -1
  561. package/dist/lib/substitution/index.mjs +0 -6
  562. package/dist/lib/substitution/index.mjs.map +1 -1
  563. package/dist/lib/substitution/observer/SubstitutionObserver.mjs +0 -6
  564. package/dist/lib/substitution/observer/SubstitutionObserver.mjs.map +1 -1
  565. package/dist/lib/substitution/observer/alignment.mjs +0 -6
  566. package/dist/lib/substitution/observer/alignment.mjs.map +1 -1
  567. package/dist/lib/substitution/observer/assertions.mjs +0 -6
  568. package/dist/lib/substitution/observer/assertions.mjs.map +1 -1
  569. package/dist/lib/substitution/observer/html-parser.mjs +0 -6
  570. package/dist/lib/substitution/observer/html-parser.mjs.map +1 -1
  571. package/dist/lib/substitution/observer/index.mjs +0 -6
  572. package/dist/lib/substitution/observer/index.mjs.map +1 -1
  573. package/dist/lib/substitution/observer/ssrf.mjs +0 -6
  574. package/dist/lib/substitution/observer/ssrf.mjs.map +1 -1
  575. package/dist/lib/substitution/rfc3986.mjs +0 -6
  576. package/dist/lib/substitution/rfc3986.mjs.map +1 -1
  577. package/dist/lib/substitution/translate.mjs +0 -6
  578. package/dist/lib/substitution/translate.mjs.map +1 -1
  579. package/dist/lib/substitution/types.mjs +0 -6
  580. package/dist/lib/substitution/vectors.mjs +0 -6
  581. package/dist/lib/substitution/vectors.mjs.map +1 -1
  582. package/dist/lib/testing/agent-tester.mjs +0 -6
  583. package/dist/lib/testing/agent-tester.mjs.map +1 -1
  584. package/dist/lib/testing/client.mjs +0 -6
  585. package/dist/lib/testing/client.mjs.map +1 -1
  586. package/dist/lib/testing/compliance/briefs.mjs +0 -6
  587. package/dist/lib/testing/compliance/briefs.mjs.map +1 -1
  588. package/dist/lib/testing/compliance/comply.mjs +0 -6
  589. package/dist/lib/testing/compliance/comply.mjs.map +1 -1
  590. package/dist/lib/testing/compliance/index.mjs +0 -6
  591. package/dist/lib/testing/compliance/index.mjs.map +1 -1
  592. package/dist/lib/testing/compliance/spec-conformance.mjs +0 -6
  593. package/dist/lib/testing/compliance/spec-conformance.mjs.map +1 -1
  594. package/dist/lib/testing/compliance/storyboard-tracks.mjs +0 -6
  595. package/dist/lib/testing/compliance/storyboard-tracks.mjs.map +1 -1
  596. package/dist/lib/testing/compliance/summary.mjs +0 -6
  597. package/dist/lib/testing/compliance/summary.mjs.map +1 -1
  598. package/dist/lib/testing/compliance/types.mjs +0 -6
  599. package/dist/lib/testing/comply-controller.mjs +0 -6
  600. package/dist/lib/testing/comply-controller.mjs.map +1 -1
  601. package/dist/lib/testing/controller-assertions.mjs +0 -6
  602. package/dist/lib/testing/controller-assertions.mjs.map +1 -1
  603. package/dist/lib/testing/formatter.mjs +0 -6
  604. package/dist/lib/testing/formatter.mjs.map +1 -1
  605. package/dist/lib/testing/index.mjs +0 -6
  606. package/dist/lib/testing/index.mjs.map +1 -1
  607. package/dist/lib/testing/local-agent-runner.mjs +0 -6
  608. package/dist/lib/testing/local-agent-runner.mjs.map +1 -1
  609. package/dist/lib/testing/orchestrator.mjs +0 -6
  610. package/dist/lib/testing/orchestrator.mjs.map +1 -1
  611. package/dist/lib/testing/personas/index.mjs +0 -6
  612. package/dist/lib/testing/personas/index.mjs.map +1 -1
  613. package/dist/lib/testing/scenarios/brand-rights.mjs +0 -6
  614. package/dist/lib/testing/scenarios/brand-rights.mjs.map +1 -1
  615. package/dist/lib/testing/scenarios/capabilities.mjs +0 -6
  616. package/dist/lib/testing/scenarios/capabilities.mjs.map +1 -1
  617. package/dist/lib/testing/scenarios/creative.mjs +0 -6
  618. package/dist/lib/testing/scenarios/creative.mjs.map +1 -1
  619. package/dist/lib/testing/scenarios/deterministic.mjs +0 -6
  620. package/dist/lib/testing/scenarios/deterministic.mjs.map +1 -1
  621. package/dist/lib/testing/scenarios/discovery.mjs +0 -6
  622. package/dist/lib/testing/scenarios/discovery.mjs.map +1 -1
  623. package/dist/lib/testing/scenarios/edge-cases.mjs +0 -6
  624. package/dist/lib/testing/scenarios/edge-cases.mjs.map +1 -1
  625. package/dist/lib/testing/scenarios/error-compliance.mjs +0 -6
  626. package/dist/lib/testing/scenarios/error-compliance.mjs.map +1 -1
  627. package/dist/lib/testing/scenarios/governance.mjs +0 -6
  628. package/dist/lib/testing/scenarios/governance.mjs.map +1 -1
  629. package/dist/lib/testing/scenarios/health.mjs +0 -6
  630. package/dist/lib/testing/scenarios/health.mjs.map +1 -1
  631. package/dist/lib/testing/scenarios/index.mjs +0 -6
  632. package/dist/lib/testing/scenarios/index.mjs.map +1 -1
  633. package/dist/lib/testing/scenarios/media-buy.mjs +0 -6
  634. package/dist/lib/testing/scenarios/media-buy.mjs.map +1 -1
  635. package/dist/lib/testing/scenarios/schema-compliance.mjs +0 -6
  636. package/dist/lib/testing/scenarios/schema-compliance.mjs.map +1 -1
  637. package/dist/lib/testing/scenarios/signals.mjs +0 -6
  638. package/dist/lib/testing/scenarios/signals.mjs.map +1 -1
  639. package/dist/lib/testing/scenarios/sponsored-intelligence.mjs +0 -6
  640. package/dist/lib/testing/scenarios/sponsored-intelligence.mjs.map +1 -1
  641. package/dist/lib/testing/scenarios/trusted-match.mjs +0 -6
  642. package/dist/lib/testing/scenarios/trusted-match.mjs.map +1 -1
  643. package/dist/lib/testing/seed-merge.mjs +0 -6
  644. package/dist/lib/testing/seed-merge.mjs.map +1 -1
  645. package/dist/lib/testing/storyboard/agent-routing.mjs +0 -6
  646. package/dist/lib/testing/storyboard/agent-routing.mjs.map +1 -1
  647. package/dist/lib/testing/storyboard/assertions.mjs +0 -6
  648. package/dist/lib/testing/storyboard/assertions.mjs.map +1 -1
  649. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +0 -6
  650. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs.map +1 -1
  651. package/dist/lib/testing/storyboard/compliance.mjs +5 -6
  652. package/dist/lib/testing/storyboard/compliance.mjs.map +1 -1
  653. package/dist/lib/testing/storyboard/context.mjs +0 -6
  654. package/dist/lib/testing/storyboard/context.mjs.map +1 -1
  655. package/dist/lib/testing/storyboard/default-invariants.mjs +0 -6
  656. package/dist/lib/testing/storyboard/default-invariants.mjs.map +1 -1
  657. package/dist/lib/testing/storyboard/index.mjs +0 -6
  658. package/dist/lib/testing/storyboard/index.mjs.map +1 -1
  659. package/dist/lib/testing/storyboard/junit.mjs +0 -6
  660. package/dist/lib/testing/storyboard/junit.mjs.map +1 -1
  661. package/dist/lib/testing/storyboard/loader.mjs +0 -6
  662. package/dist/lib/testing/storyboard/loader.mjs.map +1 -1
  663. package/dist/lib/testing/storyboard/parallel-dispatch.mjs +0 -6
  664. package/dist/lib/testing/storyboard/parallel-dispatch.mjs.map +1 -1
  665. package/dist/lib/testing/storyboard/path.mjs +0 -6
  666. package/dist/lib/testing/storyboard/path.mjs.map +1 -1
  667. package/dist/lib/testing/storyboard/probes.mjs +0 -6
  668. package/dist/lib/testing/storyboard/probes.mjs.map +1 -1
  669. package/dist/lib/testing/storyboard/rate-limit-trip.mjs +0 -6
  670. package/dist/lib/testing/storyboard/rate-limit-trip.mjs.map +1 -1
  671. package/dist/lib/testing/storyboard/rejection-hints.mjs +0 -6
  672. package/dist/lib/testing/storyboard/rejection-hints.mjs.map +1 -1
  673. package/dist/lib/testing/storyboard/request-builder.mjs +0 -6
  674. package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
  675. package/dist/lib/testing/storyboard/request-signing/builder.mjs +0 -6
  676. package/dist/lib/testing/storyboard/request-signing/builder.mjs.map +1 -1
  677. package/dist/lib/testing/storyboard/request-signing/grader.mjs +0 -6
  678. package/dist/lib/testing/storyboard/request-signing/grader.mjs.map +1 -1
  679. package/dist/lib/testing/storyboard/request-signing/index.mjs +0 -6
  680. package/dist/lib/testing/storyboard/request-signing/index.mjs.map +1 -1
  681. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +0 -6
  682. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs.map +1 -1
  683. package/dist/lib/testing/storyboard/request-signing/probe.mjs +0 -6
  684. package/dist/lib/testing/storyboard/request-signing/probe.mjs.map +1 -1
  685. package/dist/lib/testing/storyboard/request-signing/synthesize.mjs +0 -6
  686. package/dist/lib/testing/storyboard/request-signing/synthesize.mjs.map +1 -1
  687. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs +0 -6
  688. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs.map +1 -1
  689. package/dist/lib/testing/storyboard/request-signing/types.mjs +0 -6
  690. package/dist/lib/testing/storyboard/request-signing/types.mjs.map +1 -1
  691. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +0 -6
  692. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
  693. package/dist/lib/testing/storyboard/runner.mjs +0 -6
  694. package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
  695. package/dist/lib/testing/storyboard/sandbox-entities.mjs +0 -6
  696. package/dist/lib/testing/storyboard/sandbox-entities.mjs.map +1 -1
  697. package/dist/lib/testing/storyboard/seeding.mjs +0 -6
  698. package/dist/lib/testing/storyboard/seeding.mjs.map +1 -1
  699. package/dist/lib/testing/storyboard/shape-drift-hints.mjs +0 -6
  700. package/dist/lib/testing/storyboard/shape-drift-hints.mjs.map +1 -1
  701. package/dist/lib/testing/storyboard/signer-grader/grader.mjs +0 -6
  702. package/dist/lib/testing/storyboard/signer-grader/grader.mjs.map +1 -1
  703. package/dist/lib/testing/storyboard/signer-grader/index.mjs +0 -6
  704. package/dist/lib/testing/storyboard/signer-grader/index.mjs.map +1 -1
  705. package/dist/lib/testing/storyboard/signer-grader/types.mjs +0 -6
  706. package/dist/lib/testing/storyboard/strict-validation-hints.mjs +0 -6
  707. package/dist/lib/testing/storyboard/strict-validation-hints.mjs.map +1 -1
  708. package/dist/lib/testing/storyboard/task-map.mjs +0 -6
  709. package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
  710. package/dist/lib/testing/storyboard/test-kit.mjs +0 -6
  711. package/dist/lib/testing/storyboard/test-kit.mjs.map +1 -1
  712. package/dist/lib/testing/storyboard/types.mjs +0 -6
  713. package/dist/lib/testing/storyboard/types.mjs.map +1 -1
  714. package/dist/lib/testing/storyboard/validations.mjs +0 -6
  715. package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
  716. package/dist/lib/testing/storyboard/webhook-assertions.mjs +0 -6
  717. package/dist/lib/testing/storyboard/webhook-assertions.mjs.map +1 -1
  718. package/dist/lib/testing/storyboard/webhook-receiver.mjs +0 -6
  719. package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
  720. package/dist/lib/testing/stubs/governance-agent-stub.mjs +0 -6
  721. package/dist/lib/testing/stubs/governance-agent-stub.mjs.map +1 -1
  722. package/dist/lib/testing/stubs/index.mjs +0 -6
  723. package/dist/lib/testing/stubs/index.mjs.map +1 -1
  724. package/dist/lib/testing/test-controller.mjs +0 -6
  725. package/dist/lib/testing/test-controller.mjs.map +1 -1
  726. package/dist/lib/testing/test-helpers.mjs +0 -6
  727. package/dist/lib/testing/test-helpers.mjs.map +1 -1
  728. package/dist/lib/testing/types.mjs +0 -6
  729. package/dist/lib/types/adcp.mjs +0 -6
  730. package/dist/lib/types/adcp.mjs.map +1 -1
  731. package/dist/lib/types/asset-instances.mjs +0 -6
  732. package/dist/lib/types/compat.mjs +0 -6
  733. package/dist/lib/types/compat.mjs.map +1 -1
  734. package/dist/lib/types/core.generated.mjs +0 -6
  735. package/dist/lib/types/enums.generated.mjs +0 -6
  736. package/dist/lib/types/enums.generated.mjs.map +1 -1
  737. package/dist/lib/types/error-codes.mjs +0 -6
  738. package/dist/lib/types/error-codes.mjs.map +1 -1
  739. package/dist/lib/types/error-details.aliases.mjs +0 -6
  740. package/dist/lib/types/error-details.aliases.mjs.map +1 -1
  741. package/dist/lib/types/format-asset-slots.mjs +0 -6
  742. package/dist/lib/types/forward-compat-error-codes.mjs +0 -6
  743. package/dist/lib/types/forward-compat-error-codes.mjs.map +1 -1
  744. package/dist/lib/types/index.mjs +0 -6
  745. package/dist/lib/types/index.mjs.map +1 -1
  746. package/dist/lib/types/inline-enums.aliases.mjs +0 -6
  747. package/dist/lib/types/inline-enums.aliases.mjs.map +1 -1
  748. package/dist/lib/types/inline-enums.generated.mjs +0 -6
  749. package/dist/lib/types/inline-enums.generated.mjs.map +1 -1
  750. package/dist/lib/types/manifest.generated.mjs +0 -6
  751. package/dist/lib/types/manifest.generated.mjs.map +1 -1
  752. package/dist/lib/types/schemas.generated.mjs +0 -6
  753. package/dist/lib/types/schemas.generated.mjs.map +1 -1
  754. package/dist/lib/types/server-payload-aliases.mjs +0 -6
  755. package/dist/lib/types/server-payload.mjs +0 -6
  756. package/dist/lib/types/sync-rows.mjs +0 -6
  757. package/dist/lib/types/tools.generated.mjs +0 -6
  758. package/dist/lib/types/v2-5/index.mjs +0 -6
  759. package/dist/lib/types/v2-5/index.mjs.map +1 -1
  760. package/dist/lib/types/v2-5/tools.generated.mjs +0 -6
  761. package/dist/lib/types/v3-1-beta/index.mjs +0 -6
  762. package/dist/lib/types/v3-1-beta/index.mjs.map +1 -1
  763. package/dist/lib/types/v3-1-beta/tools.generated.mjs +0 -6
  764. package/dist/lib/types/wellknown-schemas.generated.mjs +0 -6
  765. package/dist/lib/types/wellknown-schemas.generated.mjs.map +1 -1
  766. package/dist/lib/upstream-recorder/constants.mjs +0 -6
  767. package/dist/lib/upstream-recorder/constants.mjs.map +1 -1
  768. package/dist/lib/upstream-recorder/index.mjs +0 -6
  769. package/dist/lib/upstream-recorder/index.mjs.map +1 -1
  770. package/dist/lib/upstream-recorder/recorder.mjs +0 -6
  771. package/dist/lib/upstream-recorder/recorder.mjs.map +1 -1
  772. package/dist/lib/upstream-recorder/types.mjs +0 -6
  773. package/dist/lib/upstream-recorder/types.mjs.map +1 -1
  774. package/dist/lib/utils/a2a-artifacts.mjs +0 -6
  775. package/dist/lib/utils/a2a-artifacts.mjs.map +1 -1
  776. package/dist/lib/utils/a2a-discovery.mjs +0 -6
  777. package/dist/lib/utils/a2a-discovery.mjs.map +1 -1
  778. package/dist/lib/utils/activation-key-builders.mjs +0 -6
  779. package/dist/lib/utils/activation-key-builders.mjs.map +1 -1
  780. package/dist/lib/utils/adcp-version-config.mjs +0 -6
  781. package/dist/lib/utils/adcp-version-config.mjs.map +1 -1
  782. package/dist/lib/utils/asset-builders.mjs +0 -6
  783. package/dist/lib/utils/asset-builders.mjs.map +1 -1
  784. package/dist/lib/utils/build-creative-return-builders.mjs +0 -6
  785. package/dist/lib/utils/build-creative-return-builders.mjs.map +1 -1
  786. package/dist/lib/utils/buyer-retry-policy.mjs +0 -6
  787. package/dist/lib/utils/buyer-retry-policy.mjs.map +1 -1
  788. package/dist/lib/utils/capabilities.mjs +0 -6
  789. package/dist/lib/utils/capabilities.mjs.map +1 -1
  790. package/dist/lib/utils/capability-rollups.mjs +0 -6
  791. package/dist/lib/utils/capability-rollups.mjs.map +1 -1
  792. package/dist/lib/utils/creative-adapter.mjs +0 -6
  793. package/dist/lib/utils/creative-adapter.mjs.map +1 -1
  794. package/dist/lib/utils/creative-delivery.mjs +0 -6
  795. package/dist/lib/utils/creative-delivery.mjs.map +1 -1
  796. package/dist/lib/utils/deprecation.mjs +0 -6
  797. package/dist/lib/utils/deprecation.mjs.map +1 -1
  798. package/dist/lib/utils/envelope-status-compat.mjs +0 -6
  799. package/dist/lib/utils/envelope-status-compat.mjs.map +1 -1
  800. package/dist/lib/utils/error-extraction.mjs +0 -6
  801. package/dist/lib/utils/error-extraction.mjs.map +1 -1
  802. package/dist/lib/utils/extract-result.mjs +0 -6
  803. package/dist/lib/utils/extract-result.mjs.map +1 -1
  804. package/dist/lib/utils/format-asset-slot-builders.mjs +0 -6
  805. package/dist/lib/utils/format-asset-slot-builders.mjs.map +1 -1
  806. package/dist/lib/utils/format-assets.mjs +0 -6
  807. package/dist/lib/utils/format-assets.mjs.map +1 -1
  808. package/dist/lib/utils/format-render-builders.mjs +0 -6
  809. package/dist/lib/utils/format-render-builders.mjs.map +1 -1
  810. package/dist/lib/utils/format-renders.mjs +0 -6
  811. package/dist/lib/utils/format-renders.mjs.map +1 -1
  812. package/dist/lib/utils/get-products-cache-scope.mjs +0 -6
  813. package/dist/lib/utils/get-products-cache-scope.mjs.map +1 -1
  814. package/dist/lib/utils/glob.mjs +0 -6
  815. package/dist/lib/utils/glob.mjs.map +1 -1
  816. package/dist/lib/utils/global-async-local-storage.mjs +0 -6
  817. package/dist/lib/utils/global-async-local-storage.mjs.map +1 -1
  818. package/dist/lib/utils/idempotency.mjs +0 -6
  819. package/dist/lib/utils/idempotency.mjs.map +1 -1
  820. package/dist/lib/utils/index.mjs +0 -6
  821. package/dist/lib/utils/index.mjs.map +1 -1
  822. package/dist/lib/utils/jcs.mjs +0 -6
  823. package/dist/lib/utils/jcs.mjs.map +1 -1
  824. package/dist/lib/utils/json-depth.mjs +0 -6
  825. package/dist/lib/utils/json-depth.mjs.map +1 -1
  826. package/dist/lib/utils/logger.mjs +0 -6
  827. package/dist/lib/utils/logger.mjs.map +1 -1
  828. package/dist/lib/utils/media-buy-delivery-notification-builders.mjs +0 -6
  829. package/dist/lib/utils/media-buy-delivery-notification-builders.mjs.map +1 -1
  830. package/dist/lib/utils/media-buy-status.mjs +0 -6
  831. package/dist/lib/utils/media-buy-status.mjs.map +1 -1
  832. package/dist/lib/utils/pagination.mjs +0 -6
  833. package/dist/lib/utils/pagination.mjs.map +1 -1
  834. package/dist/lib/utils/preview-creative-builders.mjs +0 -6
  835. package/dist/lib/utils/preview-creative-builders.mjs.map +1 -1
  836. package/dist/lib/utils/preview-normalizer.mjs +0 -6
  837. package/dist/lib/utils/preview-normalizer.mjs.map +1 -1
  838. package/dist/lib/utils/preview-utils.mjs +0 -6
  839. package/dist/lib/utils/preview-utils.mjs.map +1 -1
  840. package/dist/lib/utils/pricing-adapter.mjs +0 -6
  841. package/dist/lib/utils/pricing-adapter.mjs.map +1 -1
  842. package/dist/lib/utils/probe-policy.mjs +0 -6
  843. package/dist/lib/utils/probe-policy.mjs.map +1 -1
  844. package/dist/lib/utils/protocol-detection.mjs +0 -6
  845. package/dist/lib/utils/protocol-detection.mjs.map +1 -1
  846. package/dist/lib/utils/redact-secrets.mjs +0 -6
  847. package/dist/lib/utils/redact-secrets.mjs.map +1 -1
  848. package/dist/lib/utils/redis-default-prefix-warn.mjs +0 -6
  849. package/dist/lib/utils/redis-default-prefix-warn.mjs.map +1 -1
  850. package/dist/lib/utils/render-builders.mjs +0 -6
  851. package/dist/lib/utils/render-builders.mjs.map +1 -1
  852. package/dist/lib/utils/request-normalizer.mjs +0 -6
  853. package/dist/lib/utils/request-normalizer.mjs.map +1 -1
  854. package/dist/lib/utils/response-schemas.mjs +0 -6
  855. package/dist/lib/utils/response-schemas.mjs.map +1 -1
  856. package/dist/lib/utils/response-unwrapper.mjs +0 -6
  857. package/dist/lib/utils/response-unwrapper.mjs.map +1 -1
  858. package/dist/lib/utils/retry.mjs +0 -6
  859. package/dist/lib/utils/retry.mjs.map +1 -1
  860. package/dist/lib/utils/signal-discovery-helpers.mjs +0 -6
  861. package/dist/lib/utils/signal-discovery-helpers.mjs.map +1 -1
  862. package/dist/lib/utils/signal-id-builders.mjs +0 -6
  863. package/dist/lib/utils/signal-id-builders.mjs.map +1 -1
  864. package/dist/lib/utils/sync-creatives-adapter.mjs +0 -6
  865. package/dist/lib/utils/sync-creatives-adapter.mjs.map +1 -1
  866. package/dist/lib/utils/task-state.mjs +0 -6
  867. package/dist/lib/utils/task-state.mjs.map +1 -1
  868. package/dist/lib/utils/tool-request-schemas.mjs +0 -6
  869. package/dist/lib/utils/tool-request-schemas.mjs.map +1 -1
  870. package/dist/lib/utils/typeGuards.mjs +0 -6
  871. package/dist/lib/utils/typeGuards.mjs.map +1 -1
  872. package/dist/lib/utils/union-errors.mjs +0 -6
  873. package/dist/lib/utils/union-errors.mjs.map +1 -1
  874. package/dist/lib/utils/validate-user-agent.mjs +0 -6
  875. package/dist/lib/utils/validate-user-agent.mjs.map +1 -1
  876. package/dist/lib/v2/format-schema/fetch.mjs +0 -6
  877. package/dist/lib/v2/format-schema/fetch.mjs.map +1 -1
  878. package/dist/lib/v2/format-schema/index.mjs +0 -6
  879. package/dist/lib/v2/format-schema/index.mjs.map +1 -1
  880. package/dist/lib/v2/format-schema/regex-safety.mjs +0 -6
  881. package/dist/lib/v2/format-schema/regex-safety.mjs.map +1 -1
  882. package/dist/lib/v2/format-schema/resolver.mjs +7 -8
  883. package/dist/lib/v2/format-schema/resolver.mjs.map +1 -1
  884. package/dist/lib/v2/format-schema/sandbox-refs.mjs +0 -6
  885. package/dist/lib/v2/format-schema/sandbox-refs.mjs.map +1 -1
  886. package/dist/lib/v2/projection/augment-response.mjs +0 -6
  887. package/dist/lib/v2/projection/augment-response.mjs.map +1 -1
  888. package/dist/lib/v2/projection/builders.mjs +0 -6
  889. package/dist/lib/v2/projection/builders.mjs.map +1 -1
  890. package/dist/lib/v2/projection/cache-versions.mjs +0 -6
  891. package/dist/lib/v2/projection/cache-versions.mjs.map +1 -1
  892. package/dist/lib/v2/projection/canonical-properties.mjs +5 -6
  893. package/dist/lib/v2/projection/canonical-properties.mjs.map +1 -1
  894. package/dist/lib/v2/projection/catalog.mjs +5 -6
  895. package/dist/lib/v2/projection/catalog.mjs.map +1 -1
  896. package/dist/lib/v2/projection/constants.mjs +0 -6
  897. package/dist/lib/v2/projection/constants.mjs.map +1 -1
  898. package/dist/lib/v2/projection/index.mjs +0 -6
  899. package/dist/lib/v2/projection/index.mjs.map +1 -1
  900. package/dist/lib/v2/projection/registry.mjs +5 -6
  901. package/dist/lib/v2/projection/registry.mjs.map +1 -1
  902. package/dist/lib/v2/projection/types.mjs +0 -6
  903. package/dist/lib/v2/projection/v1-to-v2.mjs +0 -6
  904. package/dist/lib/v2/projection/v1-to-v2.mjs.map +1 -1
  905. package/dist/lib/v2/projection/v2-to-v1.mjs +0 -6
  906. package/dist/lib/v2/projection/v2-to-v1.mjs.map +1 -1
  907. package/dist/lib/v2/projection/write-side.mjs +0 -6
  908. package/dist/lib/v2/projection/write-side.mjs.map +1 -1
  909. package/dist/lib/v2/publisher-catalog/formats.mjs +0 -6
  910. package/dist/lib/v2/publisher-catalog/formats.mjs.map +1 -1
  911. package/dist/lib/v2/publisher-catalog/index.mjs +0 -6
  912. package/dist/lib/v2/publisher-catalog/index.mjs.map +1 -1
  913. package/dist/lib/validation/client-hooks.mjs +0 -6
  914. package/dist/lib/validation/client-hooks.mjs.map +1 -1
  915. package/dist/lib/validation/hints.mjs +0 -6
  916. package/dist/lib/validation/hints.mjs.map +1 -1
  917. package/dist/lib/validation/index.mjs +0 -6
  918. package/dist/lib/validation/index.mjs.map +1 -1
  919. package/dist/lib/validation/schema-errors.mjs +0 -6
  920. package/dist/lib/validation/schema-errors.mjs.map +1 -1
  921. package/dist/lib/validation/schema-loader.mjs +5 -6
  922. package/dist/lib/validation/schema-loader.mjs.map +1 -1
  923. package/dist/lib/validation/schema-validator.mjs +0 -6
  924. package/dist/lib/validation/schema-validator.mjs.map +1 -1
  925. package/dist/lib/validation/sync-creatives.mjs +0 -6
  926. package/dist/lib/validation/sync-creatives.mjs.map +1 -1
  927. package/dist/lib/version.d.mts +3 -3
  928. package/dist/lib/version.d.ts +3 -3
  929. package/dist/lib/version.js +3 -3
  930. package/dist/lib/version.js.map +1 -1
  931. package/dist/lib/version.mjs +3 -9
  932. package/dist/lib/version.mjs.map +1 -1
  933. package/dist/lib/webhooks/index.mjs +0 -6
  934. package/dist/lib/webhooks/index.mjs.map +1 -1
  935. package/dist/lib/wholesale-feed-sync/index.mjs +0 -6
  936. package/dist/lib/wholesale-feed-sync/index.mjs.map +1 -1
  937. package/dist/lib/wholesale-feed-sync/sync.mjs +0 -6
  938. package/dist/lib/wholesale-feed-sync/sync.mjs.map +1 -1
  939. package/dist/lib/wholesale-feed-sync/types.mjs +0 -6
  940. package/dist/lib/wholesale-feed-sync/webhook-notification.mjs +0 -6
  941. package/dist/lib/wholesale-feed-sync/webhook-notification.mjs.map +1 -1
  942. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/mock-server/scenario.ts"],"sourcesContent":["import { createHash, randomUUID, timingSafeEqual } from 'node:crypto';\nimport { validateHeaderName, validateHeaderValue } from 'node:http';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nconst WEBHOOK_FETCH_TIMEOUT_MS = 5000;\nconst MAX_PATH_REGEX_LENGTH = 512;\nconst MAX_SCENARIO_BODY_BYTES = 1_000_000;\nconst MAX_WEBHOOK_ATTEMPTS = 256;\nconst ALLOWED_WEBHOOK_HEADERS = new Set(['content-type', 'x-request-id', 'x-idempotency-key']);\n\nexport interface MockScenarioControllerOptions {\n specialism: string;\n controlToken?: string;\n snapshot?: () => unknown;\n reset?: () => void | Promise<void>;\n}\n\nexport interface MockScenarioScriptInput {\n match?: {\n method?: string;\n path?: string;\n path_regex?: string;\n };\n response?: {\n status?: number;\n headers?: Record<string, string>;\n body?: unknown;\n };\n delay_ms?: number;\n times?: number;\n}\n\nexport interface MockScenarioWebhookAttempt {\n webhook_id: string;\n url: string;\n payload: unknown;\n headers: Record<string, string>;\n status?: number;\n error?: string;\n emitted_at: string;\n}\n\nexport interface MockScenarioHandle {\n controlToken: string;\n reset: () => Promise<void>;\n state: () => MockScenarioState;\n addScript: (script: MockScenarioScriptInput) => string;\n clearScripts: () => void;\n}\n\nexport interface MockScenarioState {\n specialism: string;\n snapshot: unknown;\n scripts: Array<{\n script_id: string;\n match: Required<Pick<MockScenarioScript, 'method'>> & Pick<MockScenarioScript, 'path' | 'path_regex'>;\n remaining: number | null;\n created_at: string;\n }>;\n webhooks: MockScenarioWebhookAttempt[];\n idempotency: {\n entries: number;\n };\n}\n\ninterface MockScenarioScript {\n script_id: string;\n method: string;\n path?: string;\n path_regex?: string;\n path_regex_compiled?: RegExp;\n status: number;\n headers: Record<string, string>;\n body: unknown;\n delay_ms: number;\n remaining: number | null;\n created_at: string;\n}\n\nexport interface CachedIdempotentResponse {\n status: number;\n body: unknown;\n headers?: Record<string, string>;\n}\n\nexport class MockIdempotencyReplayStore {\n private readonly entries = new Map<\n string,\n {\n fingerprint: string;\n response: CachedIdempotentResponse;\n }\n >();\n\n check(\n scope: string,\n idempotencyKey: string | undefined,\n fingerprint: string\n ):\n | { kind: 'disabled' }\n | { kind: 'fresh'; record: (response: CachedIdempotentResponse) => void }\n | { kind: 'replay'; response: CachedIdempotentResponse }\n | { kind: 'conflict'; response: CachedIdempotentResponse } {\n if (!idempotencyKey) return { kind: 'disabled' };\n const key = `${scope}::${idempotencyKey}`;\n const existing = this.entries.get(key);\n if (!existing) {\n return {\n kind: 'fresh',\n record: response => {\n this.entries.set(key, { fingerprint, response });\n },\n };\n }\n if (existing.fingerprint !== fingerprint) {\n return {\n kind: 'conflict',\n response: {\n status: 409,\n body: {\n code: 'idempotency_conflict',\n message: `idempotency_key ${idempotencyKey} was previously used with a different body. Use a fresh key for distinct requests.`,\n field: 'idempotency_key',\n },\n },\n };\n }\n return { kind: 'replay', response: existing.response };\n }\n\n clear(): void {\n this.entries.clear();\n }\n\n size(): number {\n return this.entries.size;\n }\n}\n\nexport function createMockScenarioController(options: MockScenarioControllerOptions): {\n handle: MockScenarioHandle;\n idempotency: MockIdempotencyReplayStore;\n handleControlRequest: (req: IncomingMessage, res: ServerResponse, method: string, path: string) => Promise<boolean>;\n handleScriptedResponse: (\n res: ServerResponse,\n method: string,\n path: string,\n onMatch?: (method: string, path: string) => void\n ) => Promise<boolean>;\n} {\n const scripts: MockScenarioScript[] = [];\n const webhooks: MockScenarioWebhookAttempt[] = [];\n const idempotency = new MockIdempotencyReplayStore();\n const controlToken = options.controlToken ?? `ctrl_${randomUUID().replace(/-/g, '')}`;\n\n const handle: MockScenarioHandle = {\n controlToken,\n reset,\n state,\n addScript,\n clearScripts: () => {\n scripts.length = 0;\n },\n };\n\n async function reset(): Promise<void> {\n scripts.length = 0;\n webhooks.length = 0;\n idempotency.clear();\n await options.reset?.();\n }\n\n function state(): MockScenarioState {\n return {\n specialism: options.specialism,\n snapshot: options.snapshot?.() ?? {},\n scripts: scripts.map(script => ({\n script_id: script.script_id,\n match: {\n method: script.method,\n ...(script.path !== undefined && { path: script.path }),\n ...(script.path_regex !== undefined && { path_regex: script.path_regex }),\n },\n remaining: script.remaining,\n created_at: script.created_at,\n })),\n webhooks: webhooks.slice(),\n idempotency: {\n entries: idempotency.size(),\n },\n };\n }\n\n function addScript(input: MockScenarioScriptInput): string {\n const method = input.match?.method?.toUpperCase() ?? '*';\n const path = input.match?.path;\n const pathRegex = input.match?.path_regex;\n if (path && pathRegex) {\n throw new Error('scenario script match must use either path or path_regex, not both.');\n }\n if (!path && !pathRegex) {\n throw new Error('scenario script match requires path or path_regex.');\n }\n let pathRegexCompiled: RegExp | undefined;\n if (pathRegex !== undefined) {\n if (pathRegex.length > MAX_PATH_REGEX_LENGTH) {\n throw new Error(`scenario script match.path_regex must be ${MAX_PATH_REGEX_LENGTH} characters or fewer.`);\n }\n try {\n pathRegexCompiled = new RegExp(pathRegex);\n } catch {\n throw new Error('scenario script match.path_regex must be a valid regular expression.');\n }\n }\n const times = input.times === undefined ? 1 : input.times;\n if (!Number.isInteger(times) || times < 1) {\n throw new Error('scenario script times must be a positive integer.');\n }\n const status = input.response?.status ?? 500;\n if (!Number.isInteger(status) || status < 100 || status > 599) {\n throw new Error('scenario script response.status must be an HTTP status code.');\n }\n const delayMs = input.delay_ms ?? 0;\n if (!Number.isInteger(delayMs) || delayMs < 0) {\n throw new Error('scenario script delay_ms must be a non-negative integer.');\n }\n const id = `script_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n scripts.push({\n script_id: id,\n method,\n ...(path !== undefined && { path }),\n ...(pathRegex !== undefined && { path_regex: pathRegex }),\n ...(pathRegexCompiled !== undefined && { path_regex_compiled: pathRegexCompiled }),\n status,\n headers: normalizeScriptHeaders(input.response?.headers ?? {}),\n body: input.response?.body ?? {\n code: 'scripted_response',\n message: `Scripted response from ${options.specialism} mock scenario controller.`,\n },\n delay_ms: delayMs,\n remaining: times,\n created_at: new Date().toISOString(),\n });\n return id;\n }\n\n async function emitWebhook(\n url: string,\n payload: unknown,\n headers: Record<string, string> = {}\n ): Promise<MockScenarioWebhookAttempt> {\n const target = validateWebhookTarget(url);\n const attempt: MockScenarioWebhookAttempt = {\n webhook_id: `wh_${randomUUID().replace(/-/g, '').slice(0, 16)}`,\n url: target.toString(),\n payload,\n headers: filterWebhookHeaders(headers),\n emitted_at: new Date().toISOString(),\n };\n try {\n const response = await fetch(target, {\n method: 'POST',\n redirect: 'manual',\n headers: {\n 'content-type': 'application/json',\n ...attempt.headers,\n },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(WEBHOOK_FETCH_TIMEOUT_MS),\n });\n attempt.status = response.status;\n } catch {\n attempt.error = 'webhook request failed.';\n }\n recordWebhookAttempt(attempt);\n return attempt;\n }\n\n async function handleControlRequest(\n req: IncomingMessage,\n res: ServerResponse,\n method: string,\n path: string\n ): Promise<boolean> {\n if (!path.startsWith('/_scenario')) return false;\n if (!authorizeScenario(req, controlToken)) {\n writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });\n return true;\n }\n\n if (method === 'GET' && path === '/_scenario/state') {\n writeJson(res, 200, state());\n return true;\n }\n\n if (method === 'POST' && path === '/_scenario/reset') {\n await reset();\n writeJson(res, 200, { reset: true, state: state() });\n return true;\n }\n\n if (method === 'GET' && path === '/_scenario/scripts') {\n writeJson(res, 200, { scripts: state().scripts });\n return true;\n }\n\n if (method === 'DELETE' && path === '/_scenario/scripts') {\n scripts.length = 0;\n writeJson(res, 200, { cleared: true });\n return true;\n }\n\n if (method === 'POST' && path === '/_scenario/script') {\n const body = await readJsonObject(req, res);\n if (!body) return true;\n try {\n const script_id = addScript(body as MockScenarioScriptInput);\n writeJson(res, 201, { script_id });\n } catch {\n writeJson(res, 400, {\n code: 'invalid_scenario_script',\n message: 'Scenario script configuration is invalid.',\n });\n }\n return true;\n }\n\n if (method === 'GET' && path === '/_scenario/webhooks') {\n writeJson(res, 200, { webhooks: webhooks.slice() });\n return true;\n }\n\n if (method === 'POST' && path === '/_scenario/webhooks/emit') {\n const body = await readJsonObject(req, res);\n if (!body) return true;\n const url = body.url;\n if (typeof url !== 'string' || url.length === 0) {\n writeJson(res, 400, { code: 'invalid_request', message: 'url is required.' });\n return true;\n }\n const headers = isRecord(body.headers) ? stringRecord(body.headers) : {};\n try {\n const attempt = await emitWebhook(url, body.payload ?? {}, headers);\n writeJson(res, 200, attempt);\n } catch {\n writeJson(res, 400, {\n code: 'invalid_webhook_target',\n message: 'Webhook target is not allowed.',\n });\n }\n return true;\n }\n\n writeJson(res, 404, { code: 'not_found', message: `No scenario route for ${method} ${path}` });\n return true;\n }\n\n async function handleScriptedResponse(\n res: ServerResponse,\n method: string,\n path: string,\n onMatch?: (method: string, path: string) => void\n ): Promise<boolean> {\n const script = scripts.find(candidate => scriptMatches(candidate, method, path));\n if (!script) return false;\n onMatch?.(method.toUpperCase(), path);\n if (script.remaining !== null) {\n script.remaining -= 1;\n if (script.remaining <= 0) {\n const idx = scripts.indexOf(script);\n if (idx >= 0) scripts.splice(idx, 1);\n }\n }\n if (script.delay_ms > 0) {\n await new Promise(resolve => setTimeout(resolve, script.delay_ms));\n }\n writeScriptedResponse(res, script);\n return true;\n }\n\n return { handle, idempotency, handleControlRequest, handleScriptedResponse };\n\n function recordWebhookAttempt(attempt: MockScenarioWebhookAttempt): void {\n webhooks.push(attempt);\n if (webhooks.length > MAX_WEBHOOK_ATTEMPTS) {\n webhooks.splice(0, webhooks.length - MAX_WEBHOOK_ATTEMPTS);\n }\n }\n}\n\nexport function idempotencyKeyFromBody(body: Record<string, unknown>): string | undefined {\n if (typeof body.idempotency_key === 'string' && body.idempotency_key.length > 0) return body.idempotency_key;\n return undefined;\n}\n\nexport function stableFingerprint(value: unknown): string {\n return createHash('sha256').update(stableStringify(value)).digest('hex');\n}\n\nexport function writeCachedResponse(res: ServerResponse, cached: CachedIdempotentResponse): void {\n writeJson(res, cached.status, cached.body, cached.headers);\n}\n\nfunction scriptMatches(script: MockScenarioScript, method: string, path: string): boolean {\n if (script.method !== '*' && script.method !== method.toUpperCase()) return false;\n if (script.path !== undefined) return script.path === path;\n if (script.path_regex_compiled !== undefined) return script.path_regex_compiled.test(path);\n throw new Error('scenario script has no path matcher.');\n}\n\nfunction writeScriptedResponse(res: ServerResponse, script: MockScenarioScript): void {\n writeJson(res, script.status, script.body, script.headers);\n}\n\nfunction writeJson(res: ServerResponse, status: number, body: unknown, headers: Record<string, string> = {}): void {\n res.statusCode = status;\n for (const [name, value] of Object.entries(headers)) {\n res.setHeader(name, value);\n }\n if (status === 204 || body === undefined) {\n res.end();\n return;\n }\n const payload = JSON.stringify(sanitizeJsonBody(body));\n res.setHeader('content-type', headers['content-type'] ?? 'application/json; charset=utf-8');\n res.setHeader('content-length', Buffer.byteLength(payload));\n res.end(payload);\n}\n\nfunction sanitizeJsonBody(value: unknown, seen = new WeakSet<object>()): unknown {\n if (value instanceof Error) {\n return { code: 'internal_error', message: 'Internal error.' };\n }\n if (Array.isArray(value)) {\n return value.map(item => sanitizeJsonBody(item, seen));\n }\n if (isRecord(value)) {\n if (seen.has(value)) return '[Circular]';\n seen.add(value);\n const out: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) {\n if (key.toLowerCase() === 'stack') continue;\n out[key] = sanitizeJsonBody(item, seen);\n }\n seen.delete(value);\n return out;\n }\n return value;\n}\n\nasync function readJsonObject(req: IncomingMessage, res: ServerResponse): Promise<Record<string, unknown> | null> {\n const chunks: Buffer[] = [];\n let totalBytes = 0;\n for await (const chunk of req) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n totalBytes += buffer.length;\n if (totalBytes > MAX_SCENARIO_BODY_BYTES) {\n writeJson(res, 413, { code: 'request_too_large', message: 'Scenario request body is too large.' });\n return null;\n }\n chunks.push(buffer);\n }\n const raw = Buffer.concat(chunks).toString('utf8');\n if (!raw.trim()) return {};\n try {\n const parsed: unknown = JSON.parse(raw);\n if (!isRecord(parsed)) {\n writeJson(res, 400, { code: 'invalid_request', message: 'request body must be a JSON object.' });\n return null;\n }\n return parsed;\n } catch {\n writeJson(res, 400, { code: 'invalid_json', message: 'Request body must be valid JSON.' });\n return null;\n }\n}\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`;\n if (isRecord(value)) {\n return `{${Object.keys(value)\n .sort()\n .map(key => `${JSON.stringify(key)}:${stableStringify(value[key])}`)\n .join(',')}}`;\n }\n return JSON.stringify(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stringRecord(value: Record<string, unknown>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, raw] of Object.entries(value)) {\n if (typeof raw === 'string') out[key] = raw;\n }\n return out;\n}\n\nfunction normalizeScriptHeaders(headers: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, value] of Object.entries(headers)) {\n if (typeof value !== 'string') {\n throw new Error('scenario script response.headers values must be strings.');\n }\n try {\n validateHeaderName(name);\n validateHeaderValue(name, value);\n } catch {\n throw new Error('scenario script response.headers must be valid HTTP headers.');\n }\n out[name] = value;\n }\n return out;\n}\n\nfunction authorizeScenario(req: IncomingMessage, controlToken: string): boolean {\n const raw = req.headers['x-mock-control-token'];\n const got = Array.isArray(raw) ? raw[0] : raw;\n if (typeof got !== 'string') return false;\n const gotBuffer = Buffer.from(got);\n const expectedBuffer = Buffer.from(controlToken);\n return gotBuffer.length === expectedBuffer.length && timingSafeEqual(gotBuffer, expectedBuffer);\n}\n\nfunction validateWebhookTarget(raw: string): URL {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new Error('webhook target must be a valid URL.');\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error('webhook target must use http or https.');\n }\n if (url.username || url.password) {\n throw new Error('webhook target must not include credentials.');\n }\n const rawHostname = extractRawHostname(raw);\n if (!rawHostname || !isAllowedRawLoopbackWebhookHostname(rawHostname) || !isLoopbackWebhookHostname(url.hostname)) {\n throw new Error('webhook target must be loopback.');\n }\n return url;\n}\n\nfunction extractRawHostname(raw: string): string | undefined {\n const schemeIndex = raw.indexOf('://');\n if (schemeIndex < 0) return undefined;\n let authority = raw.slice(schemeIndex + 3);\n const authorityEnd = authority.search(/[/?#]/);\n if (authorityEnd >= 0) authority = authority.slice(0, authorityEnd);\n const at = authority.lastIndexOf('@');\n if (at >= 0) authority = authority.slice(at + 1);\n if (authority.startsWith('[')) {\n const close = authority.indexOf(']');\n return close >= 0 ? authority.slice(0, close + 1).toLowerCase() : undefined;\n }\n return authority.split(':')[0]?.toLowerCase();\n}\n\nfunction isAllowedRawLoopbackWebhookHostname(hostname: string): boolean {\n return (\n hostname === '127.0.0.1' ||\n hostname === '[::1]' ||\n hostname === '[::ffff:7f00:1]' ||\n hostname === '[::ffff:127.0.0.1]'\n );\n}\n\nfunction isLoopbackWebhookHostname(hostname: string): boolean {\n const normalized = hostname.replace(/^\\[/, '').replace(/\\]$/, '').toLowerCase();\n // Keep this literal-only so Node fetch never performs a DNS lookup between\n // validation and connect. Other loopback spellings are intentionally rejected.\n return normalized === '127.0.0.1' || normalized === '::1' || normalized === '::ffff:7f00:1';\n}\n\nfunction filterWebhookHeaders(headers: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, value] of Object.entries(headers)) {\n const lower = name.toLowerCase();\n if (ALLOWED_WEBHOOK_HEADERS.has(lower)) out[name] = value;\n }\n return out;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/mock-server/scenario.ts"],"sourcesContent":["import { createHash, randomUUID, timingSafeEqual } from 'node:crypto';\nimport { validateHeaderName, validateHeaderValue } from 'node:http';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nconst WEBHOOK_FETCH_TIMEOUT_MS = 5000;\nconst MAX_PATH_REGEX_LENGTH = 512;\nconst MAX_SCENARIO_BODY_BYTES = 1_000_000;\nconst MAX_WEBHOOK_ATTEMPTS = 256;\nconst ALLOWED_WEBHOOK_HEADERS = new Set(['content-type', 'x-request-id', 'x-idempotency-key']);\n\nexport interface MockScenarioControllerOptions {\n specialism: string;\n controlToken?: string;\n snapshot?: () => unknown;\n reset?: () => void | Promise<void>;\n}\n\nexport interface MockScenarioScriptInput {\n match?: {\n method?: string;\n path?: string;\n path_regex?: string;\n };\n response?: {\n status?: number;\n headers?: Record<string, string>;\n body?: unknown;\n };\n delay_ms?: number;\n times?: number;\n}\n\nexport interface MockScenarioWebhookAttempt {\n webhook_id: string;\n url: string;\n payload: unknown;\n headers: Record<string, string>;\n status?: number;\n error?: string;\n emitted_at: string;\n}\n\nexport interface MockScenarioHandle {\n controlToken: string;\n reset: () => Promise<void>;\n state: () => MockScenarioState;\n addScript: (script: MockScenarioScriptInput) => string;\n clearScripts: () => void;\n}\n\nexport interface MockScenarioState {\n specialism: string;\n snapshot: unknown;\n scripts: Array<{\n script_id: string;\n match: Required<Pick<MockScenarioScript, 'method'>> & Pick<MockScenarioScript, 'path' | 'path_regex'>;\n remaining: number | null;\n created_at: string;\n }>;\n webhooks: MockScenarioWebhookAttempt[];\n idempotency: {\n entries: number;\n };\n}\n\ninterface MockScenarioScript {\n script_id: string;\n method: string;\n path?: string;\n path_regex?: string;\n path_regex_compiled?: RegExp;\n status: number;\n headers: Record<string, string>;\n body: unknown;\n delay_ms: number;\n remaining: number | null;\n created_at: string;\n}\n\nexport interface CachedIdempotentResponse {\n status: number;\n body: unknown;\n headers?: Record<string, string>;\n}\n\nexport class MockIdempotencyReplayStore {\n private readonly entries = new Map<\n string,\n {\n fingerprint: string;\n response: CachedIdempotentResponse;\n }\n >();\n\n check(\n scope: string,\n idempotencyKey: string | undefined,\n fingerprint: string\n ):\n | { kind: 'disabled' }\n | { kind: 'fresh'; record: (response: CachedIdempotentResponse) => void }\n | { kind: 'replay'; response: CachedIdempotentResponse }\n | { kind: 'conflict'; response: CachedIdempotentResponse } {\n if (!idempotencyKey) return { kind: 'disabled' };\n const key = `${scope}::${idempotencyKey}`;\n const existing = this.entries.get(key);\n if (!existing) {\n return {\n kind: 'fresh',\n record: response => {\n this.entries.set(key, { fingerprint, response });\n },\n };\n }\n if (existing.fingerprint !== fingerprint) {\n return {\n kind: 'conflict',\n response: {\n status: 409,\n body: {\n code: 'idempotency_conflict',\n message: `idempotency_key ${idempotencyKey} was previously used with a different body. Use a fresh key for distinct requests.`,\n field: 'idempotency_key',\n },\n },\n };\n }\n return { kind: 'replay', response: existing.response };\n }\n\n clear(): void {\n this.entries.clear();\n }\n\n size(): number {\n return this.entries.size;\n }\n}\n\nexport function createMockScenarioController(options: MockScenarioControllerOptions): {\n handle: MockScenarioHandle;\n idempotency: MockIdempotencyReplayStore;\n handleControlRequest: (req: IncomingMessage, res: ServerResponse, method: string, path: string) => Promise<boolean>;\n handleScriptedResponse: (\n res: ServerResponse,\n method: string,\n path: string,\n onMatch?: (method: string, path: string) => void\n ) => Promise<boolean>;\n} {\n const scripts: MockScenarioScript[] = [];\n const webhooks: MockScenarioWebhookAttempt[] = [];\n const idempotency = new MockIdempotencyReplayStore();\n const controlToken = options.controlToken ?? `ctrl_${randomUUID().replace(/-/g, '')}`;\n\n const handle: MockScenarioHandle = {\n controlToken,\n reset,\n state,\n addScript,\n clearScripts: () => {\n scripts.length = 0;\n },\n };\n\n async function reset(): Promise<void> {\n scripts.length = 0;\n webhooks.length = 0;\n idempotency.clear();\n await options.reset?.();\n }\n\n function state(): MockScenarioState {\n return {\n specialism: options.specialism,\n snapshot: options.snapshot?.() ?? {},\n scripts: scripts.map(script => ({\n script_id: script.script_id,\n match: {\n method: script.method,\n ...(script.path !== undefined && { path: script.path }),\n ...(script.path_regex !== undefined && { path_regex: script.path_regex }),\n },\n remaining: script.remaining,\n created_at: script.created_at,\n })),\n webhooks: webhooks.slice(),\n idempotency: {\n entries: idempotency.size(),\n },\n };\n }\n\n function addScript(input: MockScenarioScriptInput): string {\n const method = input.match?.method?.toUpperCase() ?? '*';\n const path = input.match?.path;\n const pathRegex = input.match?.path_regex;\n if (path && pathRegex) {\n throw new Error('scenario script match must use either path or path_regex, not both.');\n }\n if (!path && !pathRegex) {\n throw new Error('scenario script match requires path or path_regex.');\n }\n let pathRegexCompiled: RegExp | undefined;\n if (pathRegex !== undefined) {\n if (pathRegex.length > MAX_PATH_REGEX_LENGTH) {\n throw new Error(`scenario script match.path_regex must be ${MAX_PATH_REGEX_LENGTH} characters or fewer.`);\n }\n try {\n pathRegexCompiled = new RegExp(pathRegex);\n } catch {\n throw new Error('scenario script match.path_regex must be a valid regular expression.');\n }\n }\n const times = input.times === undefined ? 1 : input.times;\n if (!Number.isInteger(times) || times < 1) {\n throw new Error('scenario script times must be a positive integer.');\n }\n const status = input.response?.status ?? 500;\n if (!Number.isInteger(status) || status < 100 || status > 599) {\n throw new Error('scenario script response.status must be an HTTP status code.');\n }\n const delayMs = input.delay_ms ?? 0;\n if (!Number.isInteger(delayMs) || delayMs < 0) {\n throw new Error('scenario script delay_ms must be a non-negative integer.');\n }\n const id = `script_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n scripts.push({\n script_id: id,\n method,\n ...(path !== undefined && { path }),\n ...(pathRegex !== undefined && { path_regex: pathRegex }),\n ...(pathRegexCompiled !== undefined && { path_regex_compiled: pathRegexCompiled }),\n status,\n headers: normalizeScriptHeaders(input.response?.headers ?? {}),\n body: input.response?.body ?? {\n code: 'scripted_response',\n message: `Scripted response from ${options.specialism} mock scenario controller.`,\n },\n delay_ms: delayMs,\n remaining: times,\n created_at: new Date().toISOString(),\n });\n return id;\n }\n\n async function emitWebhook(\n url: string,\n payload: unknown,\n headers: Record<string, string> = {}\n ): Promise<MockScenarioWebhookAttempt> {\n const target = validateWebhookTarget(url);\n const attempt: MockScenarioWebhookAttempt = {\n webhook_id: `wh_${randomUUID().replace(/-/g, '').slice(0, 16)}`,\n url: target.toString(),\n payload,\n headers: filterWebhookHeaders(headers),\n emitted_at: new Date().toISOString(),\n };\n try {\n const response = await fetch(target, {\n method: 'POST',\n redirect: 'manual',\n headers: {\n 'content-type': 'application/json',\n ...attempt.headers,\n },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(WEBHOOK_FETCH_TIMEOUT_MS),\n });\n attempt.status = response.status;\n } catch {\n attempt.error = 'webhook request failed.';\n }\n recordWebhookAttempt(attempt);\n return attempt;\n }\n\n async function handleControlRequest(\n req: IncomingMessage,\n res: ServerResponse,\n method: string,\n path: string\n ): Promise<boolean> {\n if (!path.startsWith('/_scenario')) return false;\n if (!authorizeScenario(req, controlToken)) {\n writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });\n return true;\n }\n\n if (method === 'GET' && path === '/_scenario/state') {\n writeJson(res, 200, state());\n return true;\n }\n\n if (method === 'POST' && path === '/_scenario/reset') {\n await reset();\n writeJson(res, 200, { reset: true, state: state() });\n return true;\n }\n\n if (method === 'GET' && path === '/_scenario/scripts') {\n writeJson(res, 200, { scripts: state().scripts });\n return true;\n }\n\n if (method === 'DELETE' && path === '/_scenario/scripts') {\n scripts.length = 0;\n writeJson(res, 200, { cleared: true });\n return true;\n }\n\n if (method === 'POST' && path === '/_scenario/script') {\n const body = await readJsonObject(req, res);\n if (!body) return true;\n try {\n const script_id = addScript(body as MockScenarioScriptInput);\n writeJson(res, 201, { script_id });\n } catch {\n writeJson(res, 400, {\n code: 'invalid_scenario_script',\n message: 'Scenario script configuration is invalid.',\n });\n }\n return true;\n }\n\n if (method === 'GET' && path === '/_scenario/webhooks') {\n writeJson(res, 200, { webhooks: webhooks.slice() });\n return true;\n }\n\n if (method === 'POST' && path === '/_scenario/webhooks/emit') {\n const body = await readJsonObject(req, res);\n if (!body) return true;\n const url = body.url;\n if (typeof url !== 'string' || url.length === 0) {\n writeJson(res, 400, { code: 'invalid_request', message: 'url is required.' });\n return true;\n }\n const headers = isRecord(body.headers) ? stringRecord(body.headers) : {};\n try {\n const attempt = await emitWebhook(url, body.payload ?? {}, headers);\n writeJson(res, 200, attempt);\n } catch {\n writeJson(res, 400, {\n code: 'invalid_webhook_target',\n message: 'Webhook target is not allowed.',\n });\n }\n return true;\n }\n\n writeJson(res, 404, { code: 'not_found', message: `No scenario route for ${method} ${path}` });\n return true;\n }\n\n async function handleScriptedResponse(\n res: ServerResponse,\n method: string,\n path: string,\n onMatch?: (method: string, path: string) => void\n ): Promise<boolean> {\n const script = scripts.find(candidate => scriptMatches(candidate, method, path));\n if (!script) return false;\n onMatch?.(method.toUpperCase(), path);\n if (script.remaining !== null) {\n script.remaining -= 1;\n if (script.remaining <= 0) {\n const idx = scripts.indexOf(script);\n if (idx >= 0) scripts.splice(idx, 1);\n }\n }\n if (script.delay_ms > 0) {\n await new Promise(resolve => setTimeout(resolve, script.delay_ms));\n }\n writeScriptedResponse(res, script);\n return true;\n }\n\n return { handle, idempotency, handleControlRequest, handleScriptedResponse };\n\n function recordWebhookAttempt(attempt: MockScenarioWebhookAttempt): void {\n webhooks.push(attempt);\n if (webhooks.length > MAX_WEBHOOK_ATTEMPTS) {\n webhooks.splice(0, webhooks.length - MAX_WEBHOOK_ATTEMPTS);\n }\n }\n}\n\nexport function idempotencyKeyFromBody(body: Record<string, unknown>): string | undefined {\n if (typeof body.idempotency_key === 'string' && body.idempotency_key.length > 0) return body.idempotency_key;\n return undefined;\n}\n\nexport function stableFingerprint(value: unknown): string {\n return createHash('sha256').update(stableStringify(value)).digest('hex');\n}\n\nexport function writeCachedResponse(res: ServerResponse, cached: CachedIdempotentResponse): void {\n writeJson(res, cached.status, cached.body, cached.headers);\n}\n\nfunction scriptMatches(script: MockScenarioScript, method: string, path: string): boolean {\n if (script.method !== '*' && script.method !== method.toUpperCase()) return false;\n if (script.path !== undefined) return script.path === path;\n if (script.path_regex_compiled !== undefined) return script.path_regex_compiled.test(path);\n throw new Error('scenario script has no path matcher.');\n}\n\nfunction writeScriptedResponse(res: ServerResponse, script: MockScenarioScript): void {\n writeJson(res, script.status, script.body, script.headers);\n}\n\nfunction writeJson(res: ServerResponse, status: number, body: unknown, headers: Record<string, string> = {}): void {\n res.statusCode = status;\n for (const [name, value] of Object.entries(headers)) {\n res.setHeader(name, value);\n }\n if (status === 204 || body === undefined) {\n res.end();\n return;\n }\n const payload = JSON.stringify(sanitizeJsonBody(body));\n res.setHeader('content-type', headers['content-type'] ?? 'application/json; charset=utf-8');\n res.setHeader('content-length', Buffer.byteLength(payload));\n res.end(payload);\n}\n\nfunction sanitizeJsonBody(value: unknown, seen = new WeakSet<object>()): unknown {\n if (value instanceof Error) {\n return { code: 'internal_error', message: 'Internal error.' };\n }\n if (Array.isArray(value)) {\n return value.map(item => sanitizeJsonBody(item, seen));\n }\n if (isRecord(value)) {\n if (seen.has(value)) return '[Circular]';\n seen.add(value);\n const out: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) {\n if (key.toLowerCase() === 'stack') continue;\n out[key] = sanitizeJsonBody(item, seen);\n }\n seen.delete(value);\n return out;\n }\n return value;\n}\n\nasync function readJsonObject(req: IncomingMessage, res: ServerResponse): Promise<Record<string, unknown> | null> {\n const chunks: Buffer[] = [];\n let totalBytes = 0;\n for await (const chunk of req) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n totalBytes += buffer.length;\n if (totalBytes > MAX_SCENARIO_BODY_BYTES) {\n writeJson(res, 413, { code: 'request_too_large', message: 'Scenario request body is too large.' });\n return null;\n }\n chunks.push(buffer);\n }\n const raw = Buffer.concat(chunks).toString('utf8');\n if (!raw.trim()) return {};\n try {\n const parsed: unknown = JSON.parse(raw);\n if (!isRecord(parsed)) {\n writeJson(res, 400, { code: 'invalid_request', message: 'request body must be a JSON object.' });\n return null;\n }\n return parsed;\n } catch {\n writeJson(res, 400, { code: 'invalid_json', message: 'Request body must be valid JSON.' });\n return null;\n }\n}\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`;\n if (isRecord(value)) {\n return `{${Object.keys(value)\n .sort()\n .map(key => `${JSON.stringify(key)}:${stableStringify(value[key])}`)\n .join(',')}}`;\n }\n return JSON.stringify(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stringRecord(value: Record<string, unknown>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, raw] of Object.entries(value)) {\n if (typeof raw === 'string') out[key] = raw;\n }\n return out;\n}\n\nfunction normalizeScriptHeaders(headers: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, value] of Object.entries(headers)) {\n if (typeof value !== 'string') {\n throw new Error('scenario script response.headers values must be strings.');\n }\n try {\n validateHeaderName(name);\n validateHeaderValue(name, value);\n } catch {\n throw new Error('scenario script response.headers must be valid HTTP headers.');\n }\n out[name] = value;\n }\n return out;\n}\n\nfunction authorizeScenario(req: IncomingMessage, controlToken: string): boolean {\n const raw = req.headers['x-mock-control-token'];\n const got = Array.isArray(raw) ? raw[0] : raw;\n if (typeof got !== 'string') return false;\n const gotBuffer = Buffer.from(got);\n const expectedBuffer = Buffer.from(controlToken);\n return gotBuffer.length === expectedBuffer.length && timingSafeEqual(gotBuffer, expectedBuffer);\n}\n\nfunction validateWebhookTarget(raw: string): URL {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new Error('webhook target must be a valid URL.');\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error('webhook target must use http or https.');\n }\n if (url.username || url.password) {\n throw new Error('webhook target must not include credentials.');\n }\n const rawHostname = extractRawHostname(raw);\n if (!rawHostname || !isAllowedRawLoopbackWebhookHostname(rawHostname) || !isLoopbackWebhookHostname(url.hostname)) {\n throw new Error('webhook target must be loopback.');\n }\n return url;\n}\n\nfunction extractRawHostname(raw: string): string | undefined {\n const schemeIndex = raw.indexOf('://');\n if (schemeIndex < 0) return undefined;\n let authority = raw.slice(schemeIndex + 3);\n const authorityEnd = authority.search(/[/?#]/);\n if (authorityEnd >= 0) authority = authority.slice(0, authorityEnd);\n const at = authority.lastIndexOf('@');\n if (at >= 0) authority = authority.slice(at + 1);\n if (authority.startsWith('[')) {\n const close = authority.indexOf(']');\n return close >= 0 ? authority.slice(0, close + 1).toLowerCase() : undefined;\n }\n return authority.split(':')[0]?.toLowerCase();\n}\n\nfunction isAllowedRawLoopbackWebhookHostname(hostname: string): boolean {\n return (\n hostname === '127.0.0.1' ||\n hostname === '[::1]' ||\n hostname === '[::ffff:7f00:1]' ||\n hostname === '[::ffff:127.0.0.1]'\n );\n}\n\nfunction isLoopbackWebhookHostname(hostname: string): boolean {\n const normalized = hostname.replace(/^\\[/, '').replace(/\\]$/, '').toLowerCase();\n // Keep this literal-only so Node fetch never performs a DNS lookup between\n // validation and connect. Other loopback spellings are intentionally rejected.\n return normalized === '127.0.0.1' || normalized === '::1' || normalized === '::ffff:7f00:1';\n}\n\nfunction filterWebhookHeaders(headers: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, value] of Object.entries(headers)) {\n const lower = name.toLowerCase();\n if (ALLOWED_WEBHOOK_HEADERS.has(lower)) out[name] = value;\n }\n return out;\n}\n"],"mappings":"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","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  const NOW = "2026-04-15T12:00:00Z";
8
2
  const RECENT = "2026-04-30T08:30:00Z";
9
3
  const COHORTS = [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/mock-server/signal-marketplace/seed-data.ts"],"sourcesContent":["export interface MockCohort {\n cohort_id: string;\n name: string;\n description: string;\n category: 'behavioral' | 'demographic' | 'intent' | 'contextual' | 'retargeting';\n member_count: number;\n total_universe: number;\n freshness_days: number;\n activation_status: 'active' | 'draft' | 'archived';\n data_provider_domain: string;\n data_provider_id: string;\n /** Human-readable name of the upstream data provider — flows directly to\n * AdCP `signal_id.data_provider` (required by signals response schema).\n * Without it, adapters have to fabricate the value from the domain, which\n * trains the wrong reflex. */\n data_provider_name: string;\n value_type: 'binary' | 'numeric' | 'categorical';\n range?: { min: number; max: number };\n categories?: string[];\n pricing: MockPricingTier[];\n metadata?: Record<string, unknown>;\n created_at: string;\n updated_at: string;\n}\n\nexport interface MockPricingTier {\n pricing_id: string;\n model: 'cpm';\n cpm_amount: number;\n currency: string;\n minimum_spend?: number;\n}\n\nexport interface MockDestination {\n destination_id: string;\n name: string;\n platform_type: 'dsp' | 'ssp' | 'social' | 'ctv' | 'retail' | 'agent';\n integration: 'api_push' | 'segment_id' | 'key_value' | 'agent_url';\n platform_code?: string;\n agent_url?: string;\n expected_match_rate?: number;\n}\n\nexport interface MockOperator {\n operator_id: string;\n display_name: string;\n /** AdCP-side operator identifier the adapter receives in `account.operator`. */\n adcp_operator: string;\n visible_cohort_ids: string[];\n visible_destination_ids: string[];\n /** Map of cohort_id → operator-scoped pricing override. Falls back to default pricing if absent. */\n pricing_overrides: Record<string, MockPricingTier[]>;\n}\n\nconst NOW = '2026-04-15T12:00:00Z';\nconst RECENT = '2026-04-30T08:30:00Z';\n\n/**\n * Default pricing for each cohort. Operator-specific overrides live on the\n * MockOperator entries below — this is what `op_pinnacle` (the storyboard's\n * operator) sees. A second operator in this fixture (`op_summit`) sees the\n * same Trident cohorts at a different rate.\n */\nexport const COHORTS: MockCohort[] = [\n {\n cohort_id: 'ckhsh_us_evb_2024q4_001',\n name: 'Likely EV Buyers (Trident, US)',\n description:\n 'Auto-intent shoppers showing strong EV-specific signals — model-comparison sessions, charger-locator activity, and EV-incentive content engagement.',\n category: 'intent',\n member_count: 8_000_000,\n total_universe: 100_000_000,\n freshness_days: 1,\n activation_status: 'active',\n data_provider_domain: 'tridentauto.example',\n data_provider_id: 'likely_ev_buyers',\n data_provider_name: 'Trident Auto Insights',\n value_type: 'binary',\n pricing: [\n {\n pricing_id: 'tier_default_evb_cpm',\n model: 'cpm',\n cpm_amount: 3.5,\n currency: 'USD',\n },\n ],\n metadata: { trident_taxonomy_version: '2024.4' },\n created_at: NOW,\n updated_at: RECENT,\n },\n {\n cohort_id: 'ckhsh_us_pp_2024q4_002',\n name: 'Purchase Propensity Score (Trident, US)',\n description:\n 'Per-user 0-1 propensity score for next-90-day vehicle purchase, modeled across browsing, dealership-visit, and credit-shopping signals.',\n category: 'behavioral',\n member_count: 55_000_000,\n total_universe: 100_000_000,\n freshness_days: 7,\n activation_status: 'active',\n data_provider_domain: 'tridentauto.example',\n data_provider_id: 'purchase_propensity',\n data_provider_name: 'Trident Auto Insights',\n value_type: 'numeric',\n range: { min: 0, max: 1 },\n pricing: [\n {\n pricing_id: 'tier_default_pp_cpm',\n model: 'cpm',\n cpm_amount: 4.0,\n currency: 'USD',\n },\n ],\n metadata: { trident_taxonomy_version: '2024.4' },\n created_at: NOW,\n updated_at: RECENT,\n },\n {\n cohort_id: 'ckhsh_us_cv_2024q4_003',\n name: 'Competitor Dealer Visitors (Meridian, US)',\n description:\n 'Mobile devices observed in geofenced areas around competitor auto-dealer locations within the past 30 days.',\n category: 'behavioral',\n member_count: 6_000_000,\n total_universe: 100_000_000,\n freshness_days: 3,\n activation_status: 'active',\n data_provider_domain: 'meridiangeo.example',\n data_provider_id: 'competitor_visitors',\n data_provider_name: 'Meridian Geo',\n value_type: 'binary',\n pricing: [\n {\n pricing_id: 'tier_default_cv_cpm',\n model: 'cpm',\n cpm_amount: 5.0,\n currency: 'USD',\n },\n ],\n metadata: { meridian_geo_radius_meters: 250 },\n created_at: NOW,\n updated_at: RECENT,\n },\n {\n cohort_id: 'ckhsh_us_ntb_2024q4_004',\n name: 'New-to-Brand Auto Shoppers (ShopGrid, US)',\n description:\n 'Shoppers researching auto purchases who have no prior transaction history with target brand. Built from ShopGrid retail-exhaust data.',\n category: 'intent',\n member_count: 25_000_000,\n total_universe: 100_000_000,\n freshness_days: 2,\n activation_status: 'active',\n data_provider_domain: 'shopgrid.example',\n data_provider_id: 'new_to_brand',\n data_provider_name: 'ShopGrid Retail Data',\n value_type: 'binary',\n pricing: [\n {\n pricing_id: 'tier_default_ntb_cpm',\n model: 'cpm',\n cpm_amount: 3.5,\n currency: 'USD',\n },\n ],\n metadata: { shopgrid_lookback_days: 180 },\n created_at: NOW,\n updated_at: RECENT,\n },\n];\n\nexport const DESTINATIONS: MockDestination[] = [\n {\n destination_id: 'dest_ttd_main',\n name: 'The Trade Desk — Production',\n platform_type: 'dsp',\n integration: 'segment_id',\n platform_code: 'the-trade-desk',\n expected_match_rate: 0.78,\n },\n {\n destination_id: 'dest_streamhaus_ctv',\n name: 'StreamHaus CTV',\n platform_type: 'ctv',\n integration: 'segment_id',\n platform_code: 'streamhaus',\n expected_match_rate: 0.62,\n },\n {\n destination_id: 'dest_wonderstruck_agent',\n name: 'Wonderstruck Sales Agent',\n platform_type: 'agent',\n integration: 'agent_url',\n agent_url: 'https://wonderstruck.salesagents.example',\n expected_match_rate: 0.95,\n },\n];\n\n/**\n * Mapping table the adapter has to consume. The AdCP request carries\n * `account.operator: \"pinnacle-agency.example\"`; the adapter maps that to\n * the upstream operator_id and sends `X-Operator-Id` accordingly.\n *\n * Two operators are seeded so the adapter MUST respect the mapping — using\n * the wrong operator id (or omitting the header) yields a different cohort\n * set and the storyboard fails.\n */\nexport const OPERATORS: MockOperator[] = [\n {\n operator_id: 'op_pinnacle',\n display_name: 'Pinnacle Agency',\n adcp_operator: 'pinnacle-agency.example',\n visible_cohort_ids: COHORTS.map(c => c.cohort_id),\n visible_destination_ids: DESTINATIONS.map(d => d.destination_id),\n pricing_overrides: {},\n },\n {\n operator_id: 'op_summit',\n display_name: 'Summit Media',\n adcp_operator: 'summit-media.example',\n // Only sees Trident cohorts.\n visible_cohort_ids: ['ckhsh_us_evb_2024q4_001', 'ckhsh_us_pp_2024q4_002'],\n visible_destination_ids: ['dest_ttd_main', 'dest_streamhaus_ctv'],\n // Premium rate card — same cohorts, +$1 CPM.\n pricing_overrides: {\n ckhsh_us_evb_2024q4_001: [\n {\n pricing_id: 'tier_summit_evb_cpm',\n model: 'cpm',\n cpm_amount: 4.5,\n currency: 'USD',\n minimum_spend: 10_000,\n },\n ],\n ckhsh_us_pp_2024q4_002: [\n {\n pricing_id: 'tier_summit_pp_cpm',\n model: 'cpm',\n cpm_amount: 5.0,\n currency: 'USD',\n minimum_spend: 10_000,\n },\n ],\n },\n },\n];\n\n/**\n * Default static API key shared across all operators owned by the customer.\n * Override at boot via `--api-key` if a test wants a different value.\n */\nexport const DEFAULT_API_KEY = 'mock_signal_market_key_do_not_use_in_prod';\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/mock-server/signal-marketplace/seed-data.ts"],"sourcesContent":["export interface MockCohort {\n cohort_id: string;\n name: string;\n description: string;\n category: 'behavioral' | 'demographic' | 'intent' | 'contextual' | 'retargeting';\n member_count: number;\n total_universe: number;\n freshness_days: number;\n activation_status: 'active' | 'draft' | 'archived';\n data_provider_domain: string;\n data_provider_id: string;\n /** Human-readable name of the upstream data provider — flows directly to\n * AdCP `signal_id.data_provider` (required by signals response schema).\n * Without it, adapters have to fabricate the value from the domain, which\n * trains the wrong reflex. */\n data_provider_name: string;\n value_type: 'binary' | 'numeric' | 'categorical';\n range?: { min: number; max: number };\n categories?: string[];\n pricing: MockPricingTier[];\n metadata?: Record<string, unknown>;\n created_at: string;\n updated_at: string;\n}\n\nexport interface MockPricingTier {\n pricing_id: string;\n model: 'cpm';\n cpm_amount: number;\n currency: string;\n minimum_spend?: number;\n}\n\nexport interface MockDestination {\n destination_id: string;\n name: string;\n platform_type: 'dsp' | 'ssp' | 'social' | 'ctv' | 'retail' | 'agent';\n integration: 'api_push' | 'segment_id' | 'key_value' | 'agent_url';\n platform_code?: string;\n agent_url?: string;\n expected_match_rate?: number;\n}\n\nexport interface MockOperator {\n operator_id: string;\n display_name: string;\n /** AdCP-side operator identifier the adapter receives in `account.operator`. */\n adcp_operator: string;\n visible_cohort_ids: string[];\n visible_destination_ids: string[];\n /** Map of cohort_id → operator-scoped pricing override. Falls back to default pricing if absent. */\n pricing_overrides: Record<string, MockPricingTier[]>;\n}\n\nconst NOW = '2026-04-15T12:00:00Z';\nconst RECENT = '2026-04-30T08:30:00Z';\n\n/**\n * Default pricing for each cohort. Operator-specific overrides live on the\n * MockOperator entries below — this is what `op_pinnacle` (the storyboard's\n * operator) sees. A second operator in this fixture (`op_summit`) sees the\n * same Trident cohorts at a different rate.\n */\nexport const COHORTS: MockCohort[] = [\n {\n cohort_id: 'ckhsh_us_evb_2024q4_001',\n name: 'Likely EV Buyers (Trident, US)',\n description:\n 'Auto-intent shoppers showing strong EV-specific signals — model-comparison sessions, charger-locator activity, and EV-incentive content engagement.',\n category: 'intent',\n member_count: 8_000_000,\n total_universe: 100_000_000,\n freshness_days: 1,\n activation_status: 'active',\n data_provider_domain: 'tridentauto.example',\n data_provider_id: 'likely_ev_buyers',\n data_provider_name: 'Trident Auto Insights',\n value_type: 'binary',\n pricing: [\n {\n pricing_id: 'tier_default_evb_cpm',\n model: 'cpm',\n cpm_amount: 3.5,\n currency: 'USD',\n },\n ],\n metadata: { trident_taxonomy_version: '2024.4' },\n created_at: NOW,\n updated_at: RECENT,\n },\n {\n cohort_id: 'ckhsh_us_pp_2024q4_002',\n name: 'Purchase Propensity Score (Trident, US)',\n description:\n 'Per-user 0-1 propensity score for next-90-day vehicle purchase, modeled across browsing, dealership-visit, and credit-shopping signals.',\n category: 'behavioral',\n member_count: 55_000_000,\n total_universe: 100_000_000,\n freshness_days: 7,\n activation_status: 'active',\n data_provider_domain: 'tridentauto.example',\n data_provider_id: 'purchase_propensity',\n data_provider_name: 'Trident Auto Insights',\n value_type: 'numeric',\n range: { min: 0, max: 1 },\n pricing: [\n {\n pricing_id: 'tier_default_pp_cpm',\n model: 'cpm',\n cpm_amount: 4.0,\n currency: 'USD',\n },\n ],\n metadata: { trident_taxonomy_version: '2024.4' },\n created_at: NOW,\n updated_at: RECENT,\n },\n {\n cohort_id: 'ckhsh_us_cv_2024q4_003',\n name: 'Competitor Dealer Visitors (Meridian, US)',\n description:\n 'Mobile devices observed in geofenced areas around competitor auto-dealer locations within the past 30 days.',\n category: 'behavioral',\n member_count: 6_000_000,\n total_universe: 100_000_000,\n freshness_days: 3,\n activation_status: 'active',\n data_provider_domain: 'meridiangeo.example',\n data_provider_id: 'competitor_visitors',\n data_provider_name: 'Meridian Geo',\n value_type: 'binary',\n pricing: [\n {\n pricing_id: 'tier_default_cv_cpm',\n model: 'cpm',\n cpm_amount: 5.0,\n currency: 'USD',\n },\n ],\n metadata: { meridian_geo_radius_meters: 250 },\n created_at: NOW,\n updated_at: RECENT,\n },\n {\n cohort_id: 'ckhsh_us_ntb_2024q4_004',\n name: 'New-to-Brand Auto Shoppers (ShopGrid, US)',\n description:\n 'Shoppers researching auto purchases who have no prior transaction history with target brand. Built from ShopGrid retail-exhaust data.',\n category: 'intent',\n member_count: 25_000_000,\n total_universe: 100_000_000,\n freshness_days: 2,\n activation_status: 'active',\n data_provider_domain: 'shopgrid.example',\n data_provider_id: 'new_to_brand',\n data_provider_name: 'ShopGrid Retail Data',\n value_type: 'binary',\n pricing: [\n {\n pricing_id: 'tier_default_ntb_cpm',\n model: 'cpm',\n cpm_amount: 3.5,\n currency: 'USD',\n },\n ],\n metadata: { shopgrid_lookback_days: 180 },\n created_at: NOW,\n updated_at: RECENT,\n },\n];\n\nexport const DESTINATIONS: MockDestination[] = [\n {\n destination_id: 'dest_ttd_main',\n name: 'The Trade Desk — Production',\n platform_type: 'dsp',\n integration: 'segment_id',\n platform_code: 'the-trade-desk',\n expected_match_rate: 0.78,\n },\n {\n destination_id: 'dest_streamhaus_ctv',\n name: 'StreamHaus CTV',\n platform_type: 'ctv',\n integration: 'segment_id',\n platform_code: 'streamhaus',\n expected_match_rate: 0.62,\n },\n {\n destination_id: 'dest_wonderstruck_agent',\n name: 'Wonderstruck Sales Agent',\n platform_type: 'agent',\n integration: 'agent_url',\n agent_url: 'https://wonderstruck.salesagents.example',\n expected_match_rate: 0.95,\n },\n];\n\n/**\n * Mapping table the adapter has to consume. The AdCP request carries\n * `account.operator: \"pinnacle-agency.example\"`; the adapter maps that to\n * the upstream operator_id and sends `X-Operator-Id` accordingly.\n *\n * Two operators are seeded so the adapter MUST respect the mapping — using\n * the wrong operator id (or omitting the header) yields a different cohort\n * set and the storyboard fails.\n */\nexport const OPERATORS: MockOperator[] = [\n {\n operator_id: 'op_pinnacle',\n display_name: 'Pinnacle Agency',\n adcp_operator: 'pinnacle-agency.example',\n visible_cohort_ids: COHORTS.map(c => c.cohort_id),\n visible_destination_ids: DESTINATIONS.map(d => d.destination_id),\n pricing_overrides: {},\n },\n {\n operator_id: 'op_summit',\n display_name: 'Summit Media',\n adcp_operator: 'summit-media.example',\n // Only sees Trident cohorts.\n visible_cohort_ids: ['ckhsh_us_evb_2024q4_001', 'ckhsh_us_pp_2024q4_002'],\n visible_destination_ids: ['dest_ttd_main', 'dest_streamhaus_ctv'],\n // Premium rate card — same cohorts, +$1 CPM.\n pricing_overrides: {\n ckhsh_us_evb_2024q4_001: [\n {\n pricing_id: 'tier_summit_evb_cpm',\n model: 'cpm',\n cpm_amount: 4.5,\n currency: 'USD',\n minimum_spend: 10_000,\n },\n ],\n ckhsh_us_pp_2024q4_002: [\n {\n pricing_id: 'tier_summit_pp_cpm',\n model: 'cpm',\n cpm_amount: 5.0,\n currency: 'USD',\n minimum_spend: 10_000,\n },\n ],\n },\n },\n];\n\n/**\n * Default static API key shared across all operators owned by the customer.\n * Override at boot via `--api-key` if a test wants a different value.\n */\nexport const DEFAULT_API_KEY = 'mock_signal_market_key_do_not_use_in_prod';\n"],"mappings":"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","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { createServer } from "node:http";
8
2
  import { randomUUID } from "node:crypto";
9
3
  import {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/mock-server/signal-marketplace/server.ts"],"sourcesContent":["import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { randomUUID } from 'node:crypto';\nimport {\n COHORTS,\n DEFAULT_API_KEY,\n DESTINATIONS,\n OPERATORS,\n type MockCohort,\n type MockDestination,\n type MockOperator,\n type MockPricingTier,\n} from './seed-data';\nimport {\n createMockScenarioController,\n idempotencyKeyFromBody,\n stableFingerprint,\n writeCachedResponse,\n type MockScenarioHandle,\n} from '../scenario';\n\nexport interface BootOptions {\n port: number;\n apiKey?: string;\n /** Override seed cohorts. Defaults to fixture data. */\n cohorts?: MockCohort[];\n destinations?: MockDestination[];\n operators?: MockOperator[];\n}\n\nexport interface BootResult {\n url: string;\n close: () => Promise<void>;\n scenario: MockScenarioHandle;\n}\n\nexport async function bootSignalMarketplace(options: BootOptions): Promise<BootResult> {\n const apiKey = options.apiKey ?? DEFAULT_API_KEY;\n const cohorts = options.cohorts ?? COHORTS;\n const destinations = options.destinations ?? DESTINATIONS;\n const operators = options.operators ?? OPERATORS;\n\n // Activations live in memory. Keyed by activation_id; cross-checked against\n // operator_id on read so cross-tenant leakage shows up as 403.\n const activations = new Map<string, MockActivation>();\n // client_request_id idempotency table — keyed by `<operator_id>::<client_request_id>`\n // so two operators can use the same client_request_id and not collide.\n const idempotency = new Map<string, string>();\n\n // Traffic counters keyed by `<METHOD> <route-template>`. Harness queries\n // `GET /_debug/traffic` after the storyboard run and asserts headline\n // routes were hit ≥1. Façade adapters that skip the upstream produce zero\n // counters and fail the assertion. adcontextprotocol/adcp-client#1225.\n const traffic = new Map<string, number>();\n const bump = (routeTemplate: string): void => {\n traffic.set(routeTemplate, (traffic.get(routeTemplate) ?? 0) + 1);\n };\n const scenario = createMockScenarioController({\n specialism: 'signal-marketplace',\n snapshot: () => ({\n activations: activations.size,\n idempotency: idempotency.size,\n traffic: Object.fromEntries(traffic),\n }),\n reset: () => {\n activations.clear();\n idempotency.clear();\n traffic.clear();\n },\n });\n\n const server = createServer((req, res) => {\n handleRequest(req, res, {\n apiKey,\n cohorts,\n destinations,\n operators,\n activations,\n idempotency,\n traffic,\n bump,\n scenario,\n }).catch(err => {\n // Defense-in-depth — handlers should never throw, but if one does we\n // emit a 500 with a request_id so adopter logs can still trace it.\n const requestId = (req.headers['x-request-id'] as string | undefined) ?? randomUUID();\n writeJson(res, 500, {\n code: 'internal_error',\n message: err?.message ?? 'unexpected error',\n request_id: requestId,\n });\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(options.port, '127.0.0.1', () => {\n server.removeListener('error', reject);\n resolve();\n });\n });\n\n // Use the actually-bound port. Caller may pass 0 to request an OS-assigned\n // free port (test convenience); reading address() gives the truth either way.\n const addr = server.address();\n const boundPort = typeof addr === 'object' && addr ? addr.port : options.port;\n const url = `http://127.0.0.1:${boundPort}`;\n return {\n url,\n scenario: scenario.handle,\n close: () =>\n new Promise<void>((resolve, reject) => {\n server.close(err => (err ? reject(err) : resolve()));\n }),\n };\n}\n\ninterface HandlerCtx {\n apiKey: string;\n cohorts: MockCohort[];\n destinations: MockDestination[];\n operators: MockOperator[];\n activations: Map<string, MockActivation>;\n idempotency: Map<string, string>;\n traffic: Map<string, number>;\n bump: (routeTemplate: string) => void;\n scenario: ReturnType<typeof createMockScenarioController>;\n}\n\ninterface MockActivation {\n activation_id: string;\n operator_id: string;\n cohort_id: string;\n destination_id: string;\n pricing_id: string;\n status: 'pending' | 'in_progress' | 'active' | 'failed' | 'expired';\n match_rate?: number;\n member_count_matched?: number;\n platform_segment_id?: string;\n agent_activation_key?: Record<string, string>;\n created_at: string;\n updated_at: string;\n expires_at: string;\n}\n\nasync function handleRequest(req: IncomingMessage, res: ServerResponse, ctx: HandlerCtx): Promise<void> {\n const url = new URL(req.url ?? '/', `http://127.0.0.1`);\n const path = url.pathname;\n const method = req.method ?? 'GET';\n\n if (await ctx.scenario.handleControlRequest(req, res, method, path)) return;\n\n // Façade-detection traffic dump — harness-only, no auth required.\n // Returns per-endpoint hit counts so the matrix runner can assert that\n // façade adapters (which never call upstream) fail.\n if (method === 'GET' && path === '/_debug/traffic') {\n writeJson(res, 200, { traffic: Object.fromEntries(ctx.traffic) });\n return;\n }\n\n // Discovery endpoint — replaces the hardcoded principal-mapping table the\n // harness used to inline into Claude's prompt. Adapters resolve at runtime\n // by querying with the AdCP-side identifier they receive from buyers\n // (`account.operator`, `account.brand.domain`, etc.). No auth required —\n // discovery happens before the agent has any operator context. Issue #1225.\n if (method === 'GET' && path === '/_lookup/operator') {\n ctx.bump('GET /_lookup/operator');\n const adcpOperator = url.searchParams.get('adcp_operator');\n if (!adcpOperator) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'adcp_operator query parameter is required.',\n });\n return;\n }\n const match = ctx.operators.find(o => o.adcp_operator === adcpOperator);\n if (!match) {\n writeJson(res, 404, {\n code: 'operator_not_found',\n message: `No upstream operator registered for adcp_operator=${adcpOperator}.`,\n });\n return;\n }\n writeJson(res, 200, {\n adcp_operator: match.adcp_operator,\n operator_id: match.operator_id,\n display_name: match.display_name,\n });\n return;\n }\n\n // Authentication. Order matters — surface bad-credential errors before\n // operator/cohort lookups so adopters can debug auth in isolation.\n const auth = req.headers['authorization'];\n if (!auth || !auth.startsWith('Bearer ') || auth.slice(7) !== ctx.apiKey) {\n writeJson(res, 401, { code: 'unauthorized', message: 'Missing or invalid bearer credential.' });\n return;\n }\n\n const operatorHeader = req.headers['x-operator-id'];\n const operatorId = Array.isArray(operatorHeader) ? operatorHeader[0] : operatorHeader;\n if (!operatorId) {\n writeJson(res, 403, {\n code: 'operator_required',\n message: 'X-Operator-Id header is required on every request.',\n });\n return;\n }\n const operator = ctx.operators.find(o => o.operator_id === operatorId);\n if (!operator) {\n writeJson(res, 403, {\n code: 'unknown_operator',\n message: `Unknown operator: ${operatorId}`,\n });\n return;\n }\n\n if (await ctx.scenario.handleScriptedResponse(res, method, path, (m, p) => ctx.bump(`${m} ${p}`))) return;\n\n // Bump traffic counters on each real-route hit so /_debug/traffic can\n // later report which endpoints the adapter actually exercised.\n if (method === 'GET' && path === '/v2/cohorts') {\n ctx.bump('GET /v2/cohorts');\n return handleListCohorts(url, ctx, operator, res);\n }\n const cohortMatch = path.match(/^\\/v2\\/cohorts\\/([^/]+)$/);\n if (method === 'GET' && cohortMatch && cohortMatch[1]) {\n ctx.bump('GET /v2/cohorts/{id}');\n return handleGetCohort(decodeURIComponent(cohortMatch[1]), ctx, operator, res);\n }\n if (method === 'GET' && path === '/v2/destinations') {\n ctx.bump('GET /v2/destinations');\n return handleListDestinations(ctx, operator, res);\n }\n if (method === 'POST' && path === '/v2/activations') {\n ctx.bump('POST /v2/activations');\n return handleCreateActivation(req, ctx, operator, res);\n }\n const activationMatch = path.match(/^\\/v2\\/activations\\/([^/]+)$/);\n if (method === 'GET' && activationMatch && activationMatch[1]) {\n ctx.bump('GET /v2/activations/{id}');\n return handleGetActivation(decodeURIComponent(activationMatch[1]), ctx, operator, res);\n }\n\n writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });\n}\n\nfunction handleListCohorts(url: URL, ctx: HandlerCtx, op: MockOperator, res: ServerResponse): void {\n const visible = ctx.cohorts.filter(c => op.visible_cohort_ids.includes(c.cohort_id));\n const category = url.searchParams.get('category');\n const dataProviderDomain = url.searchParams.get('data_provider_domain');\n const q = url.searchParams.get('q')?.toLowerCase();\n\n let filtered = visible;\n if (category) filtered = filtered.filter(c => c.category === category);\n if (dataProviderDomain) filtered = filtered.filter(c => c.data_provider_domain === dataProviderDomain);\n if (q) {\n filtered = filtered.filter(c => c.name.toLowerCase().includes(q) || c.description.toLowerCase().includes(q));\n }\n\n const projected = filtered.map(c => projectCohortPricing(c, op));\n writeJson(res, 200, { cohorts: projected });\n}\n\nfunction handleGetCohort(cohortId: string, ctx: HandlerCtx, op: MockOperator, res: ServerResponse): void {\n const cohort = ctx.cohorts.find(c => c.cohort_id === cohortId);\n if (!cohort) {\n writeJson(res, 404, { code: 'cohort_not_found', message: `Cohort ${cohortId} not found.` });\n return;\n }\n if (!op.visible_cohort_ids.includes(cohortId)) {\n // Distinguish \"not visible to you\" from \"doesn't exist\" — both real upstreams\n // do this and it forces the adapter to handle 403 separately from 404.\n writeJson(res, 403, {\n code: 'cohort_not_visible',\n message: `Cohort ${cohortId} is not visible to operator ${op.operator_id}.`,\n });\n return;\n }\n writeJson(res, 200, projectCohortPricing(cohort, op));\n}\n\nfunction handleListDestinations(ctx: HandlerCtx, op: MockOperator, res: ServerResponse): void {\n const visible = ctx.destinations.filter(d => op.visible_destination_ids.includes(d.destination_id));\n writeJson(res, 200, { destinations: visible });\n}\n\nasync function handleCreateActivation(\n req: IncomingMessage,\n ctx: HandlerCtx,\n op: MockOperator,\n res: ServerResponse\n): Promise<void> {\n let body: unknown;\n try {\n body = await readJson(req);\n } catch {\n writeJson(res, 400, { code: 'invalid_json', message: 'Request body must be valid JSON.' });\n return;\n }\n if (!isObject(body)) {\n writeJson(res, 400, { code: 'invalid_request', message: 'Body must be an object.' });\n return;\n }\n const exactReplay = ctx.scenario.idempotency.check(\n `${op.operator_id}::activation`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { cohort_id, destination_id, pricing_id, duration_days, client_request_id } = body as Record<string, unknown>;\n if (typeof cohort_id !== 'string' || typeof destination_id !== 'string' || typeof pricing_id !== 'string') {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'cohort_id, destination_id, and pricing_id are required strings.',\n });\n return;\n }\n\n // Idempotency replay — same client_request_id under same operator returns the\n // existing activation. Different operators using the same client_request_id\n // are independent because the table is keyed on `<operator_id>::<key>`.\n // Body equivalence: replays with mismatched (cohort_id, destination_id,\n // pricing_id) return 409 idempotency_conflict instead of silently returning\n // the original — matches Stripe's idempotency contract and the AdCP spec\n // semantics. Surfaces adapter bugs that reuse a single client_request_id\n // across logically-distinct AdCP requests instead of hiding them.\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n const idemKey = `${op.operator_id}::${client_request_id}`;\n const existing = ctx.idempotency.get(idemKey);\n if (existing) {\n const activation = ctx.activations.get(existing);\n if (activation) {\n const sameBody =\n activation.cohort_id === cohort_id &&\n activation.destination_id === destination_id &&\n activation.pricing_id === pricing_id;\n if (!sameBody) {\n writeJson(res, 409, {\n code: 'idempotency_conflict',\n message:\n `client_request_id ${client_request_id} was previously used with a different ` +\n `(cohort_id, destination_id, pricing_id) tuple. ` +\n `Use a fresh idempotency key for distinct requests.`,\n });\n return;\n }\n writeJson(res, 200, serializeActivation(activation));\n return;\n }\n }\n }\n\n const cohort = ctx.cohorts.find(c => c.cohort_id === cohort_id);\n if (!cohort || !op.visible_cohort_ids.includes(cohort_id)) {\n writeJson(res, cohort ? 403 : 404, {\n code: cohort ? 'cohort_not_visible' : 'cohort_not_found',\n message: `Cohort ${cohort_id} ${cohort ? 'not visible to operator' : 'not found'}.`,\n });\n return;\n }\n const destination = ctx.destinations.find(d => d.destination_id === destination_id);\n if (!destination || !op.visible_destination_ids.includes(destination_id)) {\n writeJson(res, destination ? 403 : 404, {\n code: destination ? 'destination_not_visible' : 'destination_not_found',\n message: `Destination ${destination_id} ${destination ? 'not visible' : 'not found'}.`,\n });\n return;\n }\n const pricingTiers = pricingForCohort(cohort, op);\n const tier = pricingTiers.find(t => t.pricing_id === pricing_id);\n if (!tier) {\n writeJson(res, 400, {\n code: 'invalid_pricing',\n message: `pricing_id ${pricing_id} is not a valid tier for this cohort under operator ${op.operator_id}.`,\n });\n return;\n }\n\n const activationId = `act_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const now = new Date();\n const expiresAt = new Date(now.getTime() + (typeof duration_days === 'number' ? duration_days : 90) * 86400_000);\n\n // Agent destinations activate synchronously (the SA records and confirms);\n // DSP/CTV destinations are async — initial pending, transitions to active\n // when the storyboard's later poll fetches.\n const isAgentDest = destination.platform_type === 'agent';\n const activation: MockActivation = {\n activation_id: activationId,\n operator_id: op.operator_id,\n cohort_id,\n destination_id,\n pricing_id,\n status: isAgentDest ? 'active' : 'pending',\n created_at: now.toISOString(),\n updated_at: now.toISOString(),\n expires_at: expiresAt.toISOString(),\n ...(isAgentDest\n ? {\n agent_activation_key: { agent_segment: cohort.data_provider_id },\n match_rate: destination.expected_match_rate ?? 0.9,\n member_count_matched: cohort.member_count,\n }\n : {}),\n };\n ctx.activations.set(activationId, activation);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n ctx.idempotency.set(`${op.operator_id}::${client_request_id}`, activationId);\n }\n\n const responseBody = serializeActivation(activation);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n}\n\nfunction handleGetActivation(activationId: string, ctx: HandlerCtx, op: MockOperator, res: ServerResponse): void {\n const activation = ctx.activations.get(activationId);\n if (!activation) {\n writeJson(res, 404, { code: 'activation_not_found', message: `Activation ${activationId} not found.` });\n return;\n }\n if (activation.operator_id !== op.operator_id) {\n // Cross-operator read attempt — surfaces as 403, not 404, so an attacker\n // can't probe activation ID space across tenants. Real platforms vary on\n // this (some return 404 to avoid existence oracles); 403 here is the\n // adopter-friendly choice for a fixture.\n writeJson(res, 403, {\n code: 'activation_not_visible',\n message: `Activation ${activationId} belongs to a different operator.`,\n });\n return;\n }\n // Auto-promote pending DSP activations to in_progress on first poll, then\n // active on second poll. Storyboard's polling loop walks this state machine.\n if (activation.status === 'pending') {\n activation.status = 'in_progress';\n activation.updated_at = new Date().toISOString();\n } else if (activation.status === 'in_progress') {\n const cohort = ctx.cohorts.find(c => c.cohort_id === activation.cohort_id);\n const destination = ctx.destinations.find(d => d.destination_id === activation.destination_id);\n activation.status = 'active';\n activation.match_rate = destination?.expected_match_rate ?? 0.75;\n activation.member_count_matched = Math.floor(\n (cohort?.member_count ?? 0) * (destination?.expected_match_rate ?? 0.75)\n );\n activation.platform_segment_id = `seg_${activation.activation_id.replace('act_', '')}`;\n activation.updated_at = new Date().toISOString();\n }\n writeJson(res, 200, serializeActivation(activation));\n}\n\nfunction projectCohortPricing(cohort: MockCohort, op: MockOperator): MockCohort {\n return {\n ...cohort,\n pricing: pricingForCohort(cohort, op),\n };\n}\n\nfunction pricingForCohort(cohort: MockCohort, op: MockOperator): MockPricingTier[] {\n const override = op.pricing_overrides[cohort.cohort_id];\n return override && override.length > 0 ? override : cohort.pricing;\n}\n\nfunction serializeActivation(a: MockActivation): Record<string, unknown> {\n // operator_id is internal book-keeping — not part of the public contract.\n const { operator_id, ...rest } = a;\n return rest;\n}\n\nfunction readJson(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', chunk => chunks.push(chunk));\n req.on('error', reject);\n req.on('end', () => {\n const raw = Buffer.concat(chunks).toString('utf8');\n if (!raw) {\n resolve({});\n return;\n }\n try {\n resolve(JSON.parse(raw));\n } catch (err) {\n reject(err);\n }\n });\n });\n}\n\nfunction writeJson(res: ServerResponse, status: number, body: unknown): void {\n const json = JSON.stringify(body);\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': Buffer.byteLength(json),\n });\n res.end(json);\n}\n\nfunction isObject(x: unknown): x is Record<string, unknown> {\n return typeof x === 'object' && x !== null && !Array.isArray(x);\n}\n"],"mappings":"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","names":["activation"]}
1
+ {"version":3,"sources":["../../../../src/lib/mock-server/signal-marketplace/server.ts"],"sourcesContent":["import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { randomUUID } from 'node:crypto';\nimport {\n COHORTS,\n DEFAULT_API_KEY,\n DESTINATIONS,\n OPERATORS,\n type MockCohort,\n type MockDestination,\n type MockOperator,\n type MockPricingTier,\n} from './seed-data';\nimport {\n createMockScenarioController,\n idempotencyKeyFromBody,\n stableFingerprint,\n writeCachedResponse,\n type MockScenarioHandle,\n} from '../scenario';\n\nexport interface BootOptions {\n port: number;\n apiKey?: string;\n /** Override seed cohorts. Defaults to fixture data. */\n cohorts?: MockCohort[];\n destinations?: MockDestination[];\n operators?: MockOperator[];\n}\n\nexport interface BootResult {\n url: string;\n close: () => Promise<void>;\n scenario: MockScenarioHandle;\n}\n\nexport async function bootSignalMarketplace(options: BootOptions): Promise<BootResult> {\n const apiKey = options.apiKey ?? DEFAULT_API_KEY;\n const cohorts = options.cohorts ?? COHORTS;\n const destinations = options.destinations ?? DESTINATIONS;\n const operators = options.operators ?? OPERATORS;\n\n // Activations live in memory. Keyed by activation_id; cross-checked against\n // operator_id on read so cross-tenant leakage shows up as 403.\n const activations = new Map<string, MockActivation>();\n // client_request_id idempotency table — keyed by `<operator_id>::<client_request_id>`\n // so two operators can use the same client_request_id and not collide.\n const idempotency = new Map<string, string>();\n\n // Traffic counters keyed by `<METHOD> <route-template>`. Harness queries\n // `GET /_debug/traffic` after the storyboard run and asserts headline\n // routes were hit ≥1. Façade adapters that skip the upstream produce zero\n // counters and fail the assertion. adcontextprotocol/adcp-client#1225.\n const traffic = new Map<string, number>();\n const bump = (routeTemplate: string): void => {\n traffic.set(routeTemplate, (traffic.get(routeTemplate) ?? 0) + 1);\n };\n const scenario = createMockScenarioController({\n specialism: 'signal-marketplace',\n snapshot: () => ({\n activations: activations.size,\n idempotency: idempotency.size,\n traffic: Object.fromEntries(traffic),\n }),\n reset: () => {\n activations.clear();\n idempotency.clear();\n traffic.clear();\n },\n });\n\n const server = createServer((req, res) => {\n handleRequest(req, res, {\n apiKey,\n cohorts,\n destinations,\n operators,\n activations,\n idempotency,\n traffic,\n bump,\n scenario,\n }).catch(err => {\n // Defense-in-depth — handlers should never throw, but if one does we\n // emit a 500 with a request_id so adopter logs can still trace it.\n const requestId = (req.headers['x-request-id'] as string | undefined) ?? randomUUID();\n writeJson(res, 500, {\n code: 'internal_error',\n message: err?.message ?? 'unexpected error',\n request_id: requestId,\n });\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(options.port, '127.0.0.1', () => {\n server.removeListener('error', reject);\n resolve();\n });\n });\n\n // Use the actually-bound port. Caller may pass 0 to request an OS-assigned\n // free port (test convenience); reading address() gives the truth either way.\n const addr = server.address();\n const boundPort = typeof addr === 'object' && addr ? addr.port : options.port;\n const url = `http://127.0.0.1:${boundPort}`;\n return {\n url,\n scenario: scenario.handle,\n close: () =>\n new Promise<void>((resolve, reject) => {\n server.close(err => (err ? reject(err) : resolve()));\n }),\n };\n}\n\ninterface HandlerCtx {\n apiKey: string;\n cohorts: MockCohort[];\n destinations: MockDestination[];\n operators: MockOperator[];\n activations: Map<string, MockActivation>;\n idempotency: Map<string, string>;\n traffic: Map<string, number>;\n bump: (routeTemplate: string) => void;\n scenario: ReturnType<typeof createMockScenarioController>;\n}\n\ninterface MockActivation {\n activation_id: string;\n operator_id: string;\n cohort_id: string;\n destination_id: string;\n pricing_id: string;\n status: 'pending' | 'in_progress' | 'active' | 'failed' | 'expired';\n match_rate?: number;\n member_count_matched?: number;\n platform_segment_id?: string;\n agent_activation_key?: Record<string, string>;\n created_at: string;\n updated_at: string;\n expires_at: string;\n}\n\nasync function handleRequest(req: IncomingMessage, res: ServerResponse, ctx: HandlerCtx): Promise<void> {\n const url = new URL(req.url ?? '/', `http://127.0.0.1`);\n const path = url.pathname;\n const method = req.method ?? 'GET';\n\n if (await ctx.scenario.handleControlRequest(req, res, method, path)) return;\n\n // Façade-detection traffic dump — harness-only, no auth required.\n // Returns per-endpoint hit counts so the matrix runner can assert that\n // façade adapters (which never call upstream) fail.\n if (method === 'GET' && path === '/_debug/traffic') {\n writeJson(res, 200, { traffic: Object.fromEntries(ctx.traffic) });\n return;\n }\n\n // Discovery endpoint — replaces the hardcoded principal-mapping table the\n // harness used to inline into Claude's prompt. Adapters resolve at runtime\n // by querying with the AdCP-side identifier they receive from buyers\n // (`account.operator`, `account.brand.domain`, etc.). No auth required —\n // discovery happens before the agent has any operator context. Issue #1225.\n if (method === 'GET' && path === '/_lookup/operator') {\n ctx.bump('GET /_lookup/operator');\n const adcpOperator = url.searchParams.get('adcp_operator');\n if (!adcpOperator) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'adcp_operator query parameter is required.',\n });\n return;\n }\n const match = ctx.operators.find(o => o.adcp_operator === adcpOperator);\n if (!match) {\n writeJson(res, 404, {\n code: 'operator_not_found',\n message: `No upstream operator registered for adcp_operator=${adcpOperator}.`,\n });\n return;\n }\n writeJson(res, 200, {\n adcp_operator: match.adcp_operator,\n operator_id: match.operator_id,\n display_name: match.display_name,\n });\n return;\n }\n\n // Authentication. Order matters — surface bad-credential errors before\n // operator/cohort lookups so adopters can debug auth in isolation.\n const auth = req.headers['authorization'];\n if (!auth || !auth.startsWith('Bearer ') || auth.slice(7) !== ctx.apiKey) {\n writeJson(res, 401, { code: 'unauthorized', message: 'Missing or invalid bearer credential.' });\n return;\n }\n\n const operatorHeader = req.headers['x-operator-id'];\n const operatorId = Array.isArray(operatorHeader) ? operatorHeader[0] : operatorHeader;\n if (!operatorId) {\n writeJson(res, 403, {\n code: 'operator_required',\n message: 'X-Operator-Id header is required on every request.',\n });\n return;\n }\n const operator = ctx.operators.find(o => o.operator_id === operatorId);\n if (!operator) {\n writeJson(res, 403, {\n code: 'unknown_operator',\n message: `Unknown operator: ${operatorId}`,\n });\n return;\n }\n\n if (await ctx.scenario.handleScriptedResponse(res, method, path, (m, p) => ctx.bump(`${m} ${p}`))) return;\n\n // Bump traffic counters on each real-route hit so /_debug/traffic can\n // later report which endpoints the adapter actually exercised.\n if (method === 'GET' && path === '/v2/cohorts') {\n ctx.bump('GET /v2/cohorts');\n return handleListCohorts(url, ctx, operator, res);\n }\n const cohortMatch = path.match(/^\\/v2\\/cohorts\\/([^/]+)$/);\n if (method === 'GET' && cohortMatch && cohortMatch[1]) {\n ctx.bump('GET /v2/cohorts/{id}');\n return handleGetCohort(decodeURIComponent(cohortMatch[1]), ctx, operator, res);\n }\n if (method === 'GET' && path === '/v2/destinations') {\n ctx.bump('GET /v2/destinations');\n return handleListDestinations(ctx, operator, res);\n }\n if (method === 'POST' && path === '/v2/activations') {\n ctx.bump('POST /v2/activations');\n return handleCreateActivation(req, ctx, operator, res);\n }\n const activationMatch = path.match(/^\\/v2\\/activations\\/([^/]+)$/);\n if (method === 'GET' && activationMatch && activationMatch[1]) {\n ctx.bump('GET /v2/activations/{id}');\n return handleGetActivation(decodeURIComponent(activationMatch[1]), ctx, operator, res);\n }\n\n writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });\n}\n\nfunction handleListCohorts(url: URL, ctx: HandlerCtx, op: MockOperator, res: ServerResponse): void {\n const visible = ctx.cohorts.filter(c => op.visible_cohort_ids.includes(c.cohort_id));\n const category = url.searchParams.get('category');\n const dataProviderDomain = url.searchParams.get('data_provider_domain');\n const q = url.searchParams.get('q')?.toLowerCase();\n\n let filtered = visible;\n if (category) filtered = filtered.filter(c => c.category === category);\n if (dataProviderDomain) filtered = filtered.filter(c => c.data_provider_domain === dataProviderDomain);\n if (q) {\n filtered = filtered.filter(c => c.name.toLowerCase().includes(q) || c.description.toLowerCase().includes(q));\n }\n\n const projected = filtered.map(c => projectCohortPricing(c, op));\n writeJson(res, 200, { cohorts: projected });\n}\n\nfunction handleGetCohort(cohortId: string, ctx: HandlerCtx, op: MockOperator, res: ServerResponse): void {\n const cohort = ctx.cohorts.find(c => c.cohort_id === cohortId);\n if (!cohort) {\n writeJson(res, 404, { code: 'cohort_not_found', message: `Cohort ${cohortId} not found.` });\n return;\n }\n if (!op.visible_cohort_ids.includes(cohortId)) {\n // Distinguish \"not visible to you\" from \"doesn't exist\" — both real upstreams\n // do this and it forces the adapter to handle 403 separately from 404.\n writeJson(res, 403, {\n code: 'cohort_not_visible',\n message: `Cohort ${cohortId} is not visible to operator ${op.operator_id}.`,\n });\n return;\n }\n writeJson(res, 200, projectCohortPricing(cohort, op));\n}\n\nfunction handleListDestinations(ctx: HandlerCtx, op: MockOperator, res: ServerResponse): void {\n const visible = ctx.destinations.filter(d => op.visible_destination_ids.includes(d.destination_id));\n writeJson(res, 200, { destinations: visible });\n}\n\nasync function handleCreateActivation(\n req: IncomingMessage,\n ctx: HandlerCtx,\n op: MockOperator,\n res: ServerResponse\n): Promise<void> {\n let body: unknown;\n try {\n body = await readJson(req);\n } catch {\n writeJson(res, 400, { code: 'invalid_json', message: 'Request body must be valid JSON.' });\n return;\n }\n if (!isObject(body)) {\n writeJson(res, 400, { code: 'invalid_request', message: 'Body must be an object.' });\n return;\n }\n const exactReplay = ctx.scenario.idempotency.check(\n `${op.operator_id}::activation`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { cohort_id, destination_id, pricing_id, duration_days, client_request_id } = body as Record<string, unknown>;\n if (typeof cohort_id !== 'string' || typeof destination_id !== 'string' || typeof pricing_id !== 'string') {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'cohort_id, destination_id, and pricing_id are required strings.',\n });\n return;\n }\n\n // Idempotency replay — same client_request_id under same operator returns the\n // existing activation. Different operators using the same client_request_id\n // are independent because the table is keyed on `<operator_id>::<key>`.\n // Body equivalence: replays with mismatched (cohort_id, destination_id,\n // pricing_id) return 409 idempotency_conflict instead of silently returning\n // the original — matches Stripe's idempotency contract and the AdCP spec\n // semantics. Surfaces adapter bugs that reuse a single client_request_id\n // across logically-distinct AdCP requests instead of hiding them.\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n const idemKey = `${op.operator_id}::${client_request_id}`;\n const existing = ctx.idempotency.get(idemKey);\n if (existing) {\n const activation = ctx.activations.get(existing);\n if (activation) {\n const sameBody =\n activation.cohort_id === cohort_id &&\n activation.destination_id === destination_id &&\n activation.pricing_id === pricing_id;\n if (!sameBody) {\n writeJson(res, 409, {\n code: 'idempotency_conflict',\n message:\n `client_request_id ${client_request_id} was previously used with a different ` +\n `(cohort_id, destination_id, pricing_id) tuple. ` +\n `Use a fresh idempotency key for distinct requests.`,\n });\n return;\n }\n writeJson(res, 200, serializeActivation(activation));\n return;\n }\n }\n }\n\n const cohort = ctx.cohorts.find(c => c.cohort_id === cohort_id);\n if (!cohort || !op.visible_cohort_ids.includes(cohort_id)) {\n writeJson(res, cohort ? 403 : 404, {\n code: cohort ? 'cohort_not_visible' : 'cohort_not_found',\n message: `Cohort ${cohort_id} ${cohort ? 'not visible to operator' : 'not found'}.`,\n });\n return;\n }\n const destination = ctx.destinations.find(d => d.destination_id === destination_id);\n if (!destination || !op.visible_destination_ids.includes(destination_id)) {\n writeJson(res, destination ? 403 : 404, {\n code: destination ? 'destination_not_visible' : 'destination_not_found',\n message: `Destination ${destination_id} ${destination ? 'not visible' : 'not found'}.`,\n });\n return;\n }\n const pricingTiers = pricingForCohort(cohort, op);\n const tier = pricingTiers.find(t => t.pricing_id === pricing_id);\n if (!tier) {\n writeJson(res, 400, {\n code: 'invalid_pricing',\n message: `pricing_id ${pricing_id} is not a valid tier for this cohort under operator ${op.operator_id}.`,\n });\n return;\n }\n\n const activationId = `act_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const now = new Date();\n const expiresAt = new Date(now.getTime() + (typeof duration_days === 'number' ? duration_days : 90) * 86400_000);\n\n // Agent destinations activate synchronously (the SA records and confirms);\n // DSP/CTV destinations are async — initial pending, transitions to active\n // when the storyboard's later poll fetches.\n const isAgentDest = destination.platform_type === 'agent';\n const activation: MockActivation = {\n activation_id: activationId,\n operator_id: op.operator_id,\n cohort_id,\n destination_id,\n pricing_id,\n status: isAgentDest ? 'active' : 'pending',\n created_at: now.toISOString(),\n updated_at: now.toISOString(),\n expires_at: expiresAt.toISOString(),\n ...(isAgentDest\n ? {\n agent_activation_key: { agent_segment: cohort.data_provider_id },\n match_rate: destination.expected_match_rate ?? 0.9,\n member_count_matched: cohort.member_count,\n }\n : {}),\n };\n ctx.activations.set(activationId, activation);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n ctx.idempotency.set(`${op.operator_id}::${client_request_id}`, activationId);\n }\n\n const responseBody = serializeActivation(activation);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n}\n\nfunction handleGetActivation(activationId: string, ctx: HandlerCtx, op: MockOperator, res: ServerResponse): void {\n const activation = ctx.activations.get(activationId);\n if (!activation) {\n writeJson(res, 404, { code: 'activation_not_found', message: `Activation ${activationId} not found.` });\n return;\n }\n if (activation.operator_id !== op.operator_id) {\n // Cross-operator read attempt — surfaces as 403, not 404, so an attacker\n // can't probe activation ID space across tenants. Real platforms vary on\n // this (some return 404 to avoid existence oracles); 403 here is the\n // adopter-friendly choice for a fixture.\n writeJson(res, 403, {\n code: 'activation_not_visible',\n message: `Activation ${activationId} belongs to a different operator.`,\n });\n return;\n }\n // Auto-promote pending DSP activations to in_progress on first poll, then\n // active on second poll. Storyboard's polling loop walks this state machine.\n if (activation.status === 'pending') {\n activation.status = 'in_progress';\n activation.updated_at = new Date().toISOString();\n } else if (activation.status === 'in_progress') {\n const cohort = ctx.cohorts.find(c => c.cohort_id === activation.cohort_id);\n const destination = ctx.destinations.find(d => d.destination_id === activation.destination_id);\n activation.status = 'active';\n activation.match_rate = destination?.expected_match_rate ?? 0.75;\n activation.member_count_matched = Math.floor(\n (cohort?.member_count ?? 0) * (destination?.expected_match_rate ?? 0.75)\n );\n activation.platform_segment_id = `seg_${activation.activation_id.replace('act_', '')}`;\n activation.updated_at = new Date().toISOString();\n }\n writeJson(res, 200, serializeActivation(activation));\n}\n\nfunction projectCohortPricing(cohort: MockCohort, op: MockOperator): MockCohort {\n return {\n ...cohort,\n pricing: pricingForCohort(cohort, op),\n };\n}\n\nfunction pricingForCohort(cohort: MockCohort, op: MockOperator): MockPricingTier[] {\n const override = op.pricing_overrides[cohort.cohort_id];\n return override && override.length > 0 ? override : cohort.pricing;\n}\n\nfunction serializeActivation(a: MockActivation): Record<string, unknown> {\n // operator_id is internal book-keeping — not part of the public contract.\n const { operator_id, ...rest } = a;\n return rest;\n}\n\nfunction readJson(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', chunk => chunks.push(chunk));\n req.on('error', reject);\n req.on('end', () => {\n const raw = Buffer.concat(chunks).toString('utf8');\n if (!raw) {\n resolve({});\n return;\n }\n try {\n resolve(JSON.parse(raw));\n } catch (err) {\n reject(err);\n }\n });\n });\n}\n\nfunction writeJson(res: ServerResponse, status: number, body: unknown): void {\n const json = JSON.stringify(body);\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': Buffer.byteLength(json),\n });\n res.end(json);\n}\n\nfunction isObject(x: unknown): x is Record<string, unknown> {\n return typeof x === 'object' && x !== null && !Array.isArray(x);\n}\n"],"mappings":"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","names":["activation"]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  const NOW = "2026-04-15T12:00:00Z";
8
2
  const OFFERING_EXPIRES = "2026-06-30T23:59:59Z";
9
3
  const OFFERINGS = [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/mock-server/sponsored-intelligence/seed-data.ts"],"sourcesContent":["export interface MockOffering {\n offering_id: string;\n brand_id: string;\n name: string;\n summary: string;\n tagline?: string;\n hero_image_url: string;\n landing_page_url: string;\n price_hint: string;\n expires_at: string;\n /** Upstream product catalog tied to this offering. The adapter projects\n * these to the `matching_products` array on `SIGetOfferingResponse` when\n * `include_products` is true. Note the upstream key is `sku` and AdCP\n * wants `product_id` — direct rename, intentional, exercises the\n * adapter's projection. */\n products: MockProduct[];\n}\n\nexport interface MockProduct {\n sku: string;\n name: string;\n display_price: string;\n list_price?: string;\n thumbnail_url: string;\n pdp_url: string;\n inventory_status: string;\n}\n\nexport interface MockBrand {\n brand_id: string;\n display_name: string;\n /** AdCP-side identifier the adapter receives in `account.brand` (or\n * however the adopter chooses to project brand identity). The adapter\n * resolves this to `brand_id` for outbound URL composition. */\n adcp_brand: string;\n /** Privacy policy version surfaced in `SIInitiateSessionResponse.identity`\n * acknowledgment when the host shares user data with consent. */\n privacy_policy_url: string;\n privacy_policy_version: string;\n visible_offering_ids: string[];\n /** Default session inactivity timeout the brand wants the host to honor.\n * Mirrors AdCP's `session_ttl_seconds` on the initiate response. */\n session_ttl_seconds: number;\n}\n\nconst NOW = '2026-04-15T12:00:00Z';\nconst OFFERING_EXPIRES = '2026-06-30T23:59:59Z';\n\nexport const OFFERINGS: MockOffering[] = [\n {\n offering_id: 'off_acme_trailrun_summer26',\n brand_id: 'brand_acme_outdoor',\n name: 'Trail Runner Summer Collection',\n summary:\n 'Lightweight trail-running shoes with grippy lugs and breathable mesh — built for the long haul. Free returns within 30 days.',\n tagline: 'Built for the trail.',\n hero_image_url: 'https://test-assets.adcontextprotocol.org/acme-outdoor/trailrun-hero.jpg',\n landing_page_url: 'https://acmeoutdoor.example/trailrun',\n price_hint: 'from $129',\n expires_at: OFFERING_EXPIRES,\n products: [\n {\n sku: 'acme_tr_blackgreen_10',\n name: 'Trail Runner — Black/Green, M10',\n display_price: '$129',\n list_price: '$159',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/acme-outdoor/tr-blackgreen-10.jpg',\n pdp_url: 'https://acmeoutdoor.example/trailrun/blackgreen-10',\n inventory_status: 'In stock',\n },\n {\n sku: 'acme_tr_charcoal_11',\n name: 'Trail Runner — Charcoal, M11',\n display_price: '$129',\n list_price: '$159',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/acme-outdoor/tr-charcoal-11.jpg',\n pdp_url: 'https://acmeoutdoor.example/trailrun/charcoal-11',\n inventory_status: 'Only 3 left',\n },\n ],\n },\n {\n offering_id: 'off_summit_books_summer26',\n brand_id: 'brand_summit_books',\n name: 'Summer Reading Picks',\n summary:\n 'Hand-picked reading list from independent booksellers — fiction, memoir, nature writing. Free shipping on orders over $35.',\n tagline: 'Your next favorite book is here.',\n hero_image_url: 'https://test-assets.adcontextprotocol.org/summit-books/summer-hero.jpg',\n landing_page_url: 'https://summit-books.example/summer',\n price_hint: 'from $18',\n expires_at: OFFERING_EXPIRES,\n products: [\n {\n sku: 'sb_book_river_north',\n name: 'River North — A Novel (paperback)',\n display_price: '$18',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/summit-books/river-north.jpg',\n pdp_url: 'https://summit-books.example/books/river-north',\n inventory_status: 'In stock',\n },\n ],\n },\n {\n // Nova Motors offering matching the canonical compliance test-kit\n // (`compliance/cache/latest/test-kits/nova-motors.yaml`). The\n // `si_baseline` storyboard at\n // `compliance/cache/latest/protocols/sponsored-intelligence/index.yaml`\n // requests this `offering_id` directly. Seeding it here lets the SI\n // mock be the canonical fixture for SI compliance runs.\n offering_id: 'novamotors_conversational_v1',\n brand_id: 'brand_nova_motors',\n name: 'Nova Motors Volta EV — Conversational Concierge',\n summary:\n 'Talk to the Nova Motors product team about the Volta EV. Range, charging network, lease vs. buy, dealer locator — answered in plain language by an AI concierge backed by real specs.',\n tagline: 'Engineering meets sustainability.',\n hero_image_url: 'https://test-assets.adcontextprotocol.org/nova-motors/volta-hero.jpg',\n landing_page_url: 'https://novamotors.example/volta',\n price_hint: 'from $42,500',\n expires_at: OFFERING_EXPIRES,\n products: [\n {\n sku: 'nova_volta_long_range_awd',\n name: 'Volta EV Long Range AWD',\n display_price: '$48,900',\n list_price: '$52,400',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/nova-motors/volta-long-range.jpg',\n pdp_url: 'https://novamotors.example/volta/long-range-awd',\n inventory_status: 'Available now — 2 in stock at nearest dealer',\n },\n {\n sku: 'nova_volta_standard_rwd',\n name: 'Volta EV Standard RWD',\n display_price: '$42,500',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/nova-motors/volta-standard.jpg',\n pdp_url: 'https://novamotors.example/volta/standard-rwd',\n inventory_status: 'Build-to-order — 6 week delivery',\n },\n ],\n },\n];\n\nexport const BRANDS: MockBrand[] = [\n {\n brand_id: 'brand_acme_outdoor',\n display_name: 'Acme Outdoor',\n adcp_brand: 'acmeoutdoor.example',\n privacy_policy_url: 'https://acmeoutdoor.example/privacy',\n privacy_policy_version: '2026-01-01',\n visible_offering_ids: ['off_acme_trailrun_summer26'],\n session_ttl_seconds: 600,\n },\n {\n brand_id: 'brand_summit_books',\n display_name: 'Summit Books',\n adcp_brand: 'summit-books.example',\n privacy_policy_url: 'https://summit-books.example/privacy',\n privacy_policy_version: '2025-09-15',\n visible_offering_ids: ['off_summit_books_summer26'],\n session_ttl_seconds: 900,\n },\n {\n // Nova Motors — canonical compliance fixture. Brand identity matches\n // `compliance/cache/latest/test-kits/nova-motors.yaml` so the\n // `si_baseline` storyboard runs cleanly against the mock.\n brand_id: 'brand_nova_motors',\n display_name: 'Nova Motors',\n adcp_brand: 'novamotors.example',\n privacy_policy_url: 'https://novamotors.example/privacy',\n privacy_policy_version: '2026-02-01',\n visible_offering_ids: ['novamotors_conversational_v1'],\n session_ttl_seconds: 1200,\n },\n];\n\n/** Default static API key shared across all brands owned by the customer. */\nexport const DEFAULT_API_KEY = 'mock_si_brand_key_do_not_use_in_prod';\n\n/** Stable timestamp returned by `created_at` fields on conversation and turn\n * records. Tests pin against this for deterministic assertions. */\nexport const SEED_NOW = NOW;\n"],"mappings":";;;;;;AA6CA,MAAM,MAAM;AACZ,MAAM,mBAAmB;AAElB,MAAM,YAA4B;AAAA,EACvC;AAAA,IACE,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,SACE;AAAA,IACF,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,MACA;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,SACE;AAAA,IACF,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOE,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,SACE;AAAA,IACF,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,MACA;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,SAAsB;AAAA,EACjC;AAAA,IACE,UAAU;AAAA,IACV,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,wBAAwB;AAAA,IACxB,sBAAsB,CAAC,4BAA4B;AAAA,IACnD,qBAAqB;AAAA,EACvB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,wBAAwB;AAAA,IACxB,sBAAsB,CAAC,2BAA2B;AAAA,IAClD,qBAAqB;AAAA,EACvB;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,IAIE,UAAU;AAAA,IACV,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,wBAAwB;AAAA,IACxB,sBAAsB,CAAC,8BAA8B;AAAA,IACrD,qBAAqB;AAAA,EACvB;AACF;AAGO,MAAM,kBAAkB;AAIxB,MAAM,WAAW;","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/mock-server/sponsored-intelligence/seed-data.ts"],"sourcesContent":["export interface MockOffering {\n offering_id: string;\n brand_id: string;\n name: string;\n summary: string;\n tagline?: string;\n hero_image_url: string;\n landing_page_url: string;\n price_hint: string;\n expires_at: string;\n /** Upstream product catalog tied to this offering. The adapter projects\n * these to the `matching_products` array on `SIGetOfferingResponse` when\n * `include_products` is true. Note the upstream key is `sku` and AdCP\n * wants `product_id` — direct rename, intentional, exercises the\n * adapter's projection. */\n products: MockProduct[];\n}\n\nexport interface MockProduct {\n sku: string;\n name: string;\n display_price: string;\n list_price?: string;\n thumbnail_url: string;\n pdp_url: string;\n inventory_status: string;\n}\n\nexport interface MockBrand {\n brand_id: string;\n display_name: string;\n /** AdCP-side identifier the adapter receives in `account.brand` (or\n * however the adopter chooses to project brand identity). The adapter\n * resolves this to `brand_id` for outbound URL composition. */\n adcp_brand: string;\n /** Privacy policy version surfaced in `SIInitiateSessionResponse.identity`\n * acknowledgment when the host shares user data with consent. */\n privacy_policy_url: string;\n privacy_policy_version: string;\n visible_offering_ids: string[];\n /** Default session inactivity timeout the brand wants the host to honor.\n * Mirrors AdCP's `session_ttl_seconds` on the initiate response. */\n session_ttl_seconds: number;\n}\n\nconst NOW = '2026-04-15T12:00:00Z';\nconst OFFERING_EXPIRES = '2026-06-30T23:59:59Z';\n\nexport const OFFERINGS: MockOffering[] = [\n {\n offering_id: 'off_acme_trailrun_summer26',\n brand_id: 'brand_acme_outdoor',\n name: 'Trail Runner Summer Collection',\n summary:\n 'Lightweight trail-running shoes with grippy lugs and breathable mesh — built for the long haul. Free returns within 30 days.',\n tagline: 'Built for the trail.',\n hero_image_url: 'https://test-assets.adcontextprotocol.org/acme-outdoor/trailrun-hero.jpg',\n landing_page_url: 'https://acmeoutdoor.example/trailrun',\n price_hint: 'from $129',\n expires_at: OFFERING_EXPIRES,\n products: [\n {\n sku: 'acme_tr_blackgreen_10',\n name: 'Trail Runner — Black/Green, M10',\n display_price: '$129',\n list_price: '$159',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/acme-outdoor/tr-blackgreen-10.jpg',\n pdp_url: 'https://acmeoutdoor.example/trailrun/blackgreen-10',\n inventory_status: 'In stock',\n },\n {\n sku: 'acme_tr_charcoal_11',\n name: 'Trail Runner — Charcoal, M11',\n display_price: '$129',\n list_price: '$159',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/acme-outdoor/tr-charcoal-11.jpg',\n pdp_url: 'https://acmeoutdoor.example/trailrun/charcoal-11',\n inventory_status: 'Only 3 left',\n },\n ],\n },\n {\n offering_id: 'off_summit_books_summer26',\n brand_id: 'brand_summit_books',\n name: 'Summer Reading Picks',\n summary:\n 'Hand-picked reading list from independent booksellers — fiction, memoir, nature writing. Free shipping on orders over $35.',\n tagline: 'Your next favorite book is here.',\n hero_image_url: 'https://test-assets.adcontextprotocol.org/summit-books/summer-hero.jpg',\n landing_page_url: 'https://summit-books.example/summer',\n price_hint: 'from $18',\n expires_at: OFFERING_EXPIRES,\n products: [\n {\n sku: 'sb_book_river_north',\n name: 'River North — A Novel (paperback)',\n display_price: '$18',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/summit-books/river-north.jpg',\n pdp_url: 'https://summit-books.example/books/river-north',\n inventory_status: 'In stock',\n },\n ],\n },\n {\n // Nova Motors offering matching the canonical compliance test-kit\n // (`compliance/cache/latest/test-kits/nova-motors.yaml`). The\n // `si_baseline` storyboard at\n // `compliance/cache/latest/protocols/sponsored-intelligence/index.yaml`\n // requests this `offering_id` directly. Seeding it here lets the SI\n // mock be the canonical fixture for SI compliance runs.\n offering_id: 'novamotors_conversational_v1',\n brand_id: 'brand_nova_motors',\n name: 'Nova Motors Volta EV — Conversational Concierge',\n summary:\n 'Talk to the Nova Motors product team about the Volta EV. Range, charging network, lease vs. buy, dealer locator — answered in plain language by an AI concierge backed by real specs.',\n tagline: 'Engineering meets sustainability.',\n hero_image_url: 'https://test-assets.adcontextprotocol.org/nova-motors/volta-hero.jpg',\n landing_page_url: 'https://novamotors.example/volta',\n price_hint: 'from $42,500',\n expires_at: OFFERING_EXPIRES,\n products: [\n {\n sku: 'nova_volta_long_range_awd',\n name: 'Volta EV Long Range AWD',\n display_price: '$48,900',\n list_price: '$52,400',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/nova-motors/volta-long-range.jpg',\n pdp_url: 'https://novamotors.example/volta/long-range-awd',\n inventory_status: 'Available now — 2 in stock at nearest dealer',\n },\n {\n sku: 'nova_volta_standard_rwd',\n name: 'Volta EV Standard RWD',\n display_price: '$42,500',\n thumbnail_url: 'https://test-assets.adcontextprotocol.org/nova-motors/volta-standard.jpg',\n pdp_url: 'https://novamotors.example/volta/standard-rwd',\n inventory_status: 'Build-to-order — 6 week delivery',\n },\n ],\n },\n];\n\nexport const BRANDS: MockBrand[] = [\n {\n brand_id: 'brand_acme_outdoor',\n display_name: 'Acme Outdoor',\n adcp_brand: 'acmeoutdoor.example',\n privacy_policy_url: 'https://acmeoutdoor.example/privacy',\n privacy_policy_version: '2026-01-01',\n visible_offering_ids: ['off_acme_trailrun_summer26'],\n session_ttl_seconds: 600,\n },\n {\n brand_id: 'brand_summit_books',\n display_name: 'Summit Books',\n adcp_brand: 'summit-books.example',\n privacy_policy_url: 'https://summit-books.example/privacy',\n privacy_policy_version: '2025-09-15',\n visible_offering_ids: ['off_summit_books_summer26'],\n session_ttl_seconds: 900,\n },\n {\n // Nova Motors — canonical compliance fixture. Brand identity matches\n // `compliance/cache/latest/test-kits/nova-motors.yaml` so the\n // `si_baseline` storyboard runs cleanly against the mock.\n brand_id: 'brand_nova_motors',\n display_name: 'Nova Motors',\n adcp_brand: 'novamotors.example',\n privacy_policy_url: 'https://novamotors.example/privacy',\n privacy_policy_version: '2026-02-01',\n visible_offering_ids: ['novamotors_conversational_v1'],\n session_ttl_seconds: 1200,\n },\n];\n\n/** Default static API key shared across all brands owned by the customer. */\nexport const DEFAULT_API_KEY = 'mock_si_brand_key_do_not_use_in_prod';\n\n/** Stable timestamp returned by `created_at` fields on conversation and turn\n * records. Tests pin against this for deterministic assertions. */\nexport const SEED_NOW = NOW;\n"],"mappings":"AA6CA,MAAM,MAAM;AACZ,MAAM,mBAAmB;AAElB,MAAM,YAA4B;AAAA,EACvC;AAAA,IACE,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,SACE;AAAA,IACF,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,MACA;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,SACE;AAAA,IACF,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOE,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,SACE;AAAA,IACF,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,MACA;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,eAAe;AAAA,QACf,eAAe;AAAA,QACf,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,SAAsB;AAAA,EACjC;AAAA,IACE,UAAU;AAAA,IACV,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,wBAAwB;AAAA,IACxB,sBAAsB,CAAC,4BAA4B;AAAA,IACnD,qBAAqB;AAAA,EACvB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,wBAAwB;AAAA,IACxB,sBAAsB,CAAC,2BAA2B;AAAA,IAClD,qBAAqB;AAAA,EACvB;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,IAIE,UAAU;AAAA,IACV,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,wBAAwB;AAAA,IACxB,sBAAsB,CAAC,8BAA8B;AAAA,IACrD,qBAAqB;AAAA,EACvB;AACF;AAGO,MAAM,kBAAkB;AAIxB,MAAM,WAAW;","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { createServer } from "node:http";
8
2
  import { randomUUID } from "node:crypto";
9
3
  import { BRANDS, DEFAULT_API_KEY, OFFERINGS } from "./seed-data.mjs";