@adcp/sdk 8.1.0-beta.13 → 8.1.0-beta.14

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 (363) hide show
  1. package/README.md +1 -1
  2. package/bin/adcp-registry.js +2 -2
  3. package/dist/lib/canonical-references/index.d.ts +107 -0
  4. package/dist/lib/canonical-references/index.d.ts.map +1 -0
  5. package/dist/lib/canonical-references/index.js +551 -0
  6. package/dist/lib/canonical-references/index.js.map +1 -0
  7. package/dist/lib/core/ConversationTypes.d.ts +7 -0
  8. package/dist/lib/core/ConversationTypes.d.ts.map +1 -1
  9. package/dist/lib/core/ProtocolResponseParser.d.ts +10 -0
  10. package/dist/lib/core/ProtocolResponseParser.d.ts.map +1 -1
  11. package/dist/lib/core/ProtocolResponseParser.js +110 -0
  12. package/dist/lib/core/ProtocolResponseParser.js.map +1 -1
  13. package/dist/lib/core/ResponseValidator.d.ts +2 -0
  14. package/dist/lib/core/ResponseValidator.d.ts.map +1 -1
  15. package/dist/lib/core/ResponseValidator.js +3 -3
  16. package/dist/lib/core/ResponseValidator.js.map +1 -1
  17. package/dist/lib/core/TaskExecutor.d.ts +2 -0
  18. package/dist/lib/core/TaskExecutor.d.ts.map +1 -1
  19. package/dist/lib/core/TaskExecutor.js +32 -8
  20. package/dist/lib/core/TaskExecutor.js.map +1 -1
  21. package/dist/lib/index.d.ts +5 -4
  22. package/dist/lib/index.d.ts.map +1 -1
  23. package/dist/lib/index.js +27 -11
  24. package/dist/lib/index.js.map +1 -1
  25. package/dist/lib/mock-server/creative-ad-server/server.d.ts +2 -0
  26. package/dist/lib/mock-server/creative-ad-server/server.d.ts.map +1 -1
  27. package/dist/lib/mock-server/creative-ad-server/server.js +37 -1
  28. package/dist/lib/mock-server/creative-ad-server/server.js.map +1 -1
  29. package/dist/lib/mock-server/creative-template/server.d.ts +2 -0
  30. package/dist/lib/mock-server/creative-template/server.d.ts.map +1 -1
  31. package/dist/lib/mock-server/creative-template/server.js +29 -2
  32. package/dist/lib/mock-server/creative-template/server.js.map +1 -1
  33. package/dist/lib/mock-server/index.d.ts +10 -1
  34. package/dist/lib/mock-server/index.d.ts.map +1 -1
  35. package/dist/lib/mock-server/index.js +38 -8
  36. package/dist/lib/mock-server/index.js.map +1 -1
  37. package/dist/lib/mock-server/sales-guaranteed/server.d.ts +2 -0
  38. package/dist/lib/mock-server/sales-guaranteed/server.d.ts.map +1 -1
  39. package/dist/lib/mock-server/sales-guaranteed/server.js +64 -7
  40. package/dist/lib/mock-server/sales-guaranteed/server.js.map +1 -1
  41. package/dist/lib/mock-server/sales-non-guaranteed/server.d.ts +2 -0
  42. package/dist/lib/mock-server/sales-non-guaranteed/server.d.ts.map +1 -1
  43. package/dist/lib/mock-server/sales-non-guaranteed/server.js +44 -1
  44. package/dist/lib/mock-server/sales-non-guaranteed/server.js.map +1 -1
  45. package/dist/lib/mock-server/sales-social/server.d.ts +2 -0
  46. package/dist/lib/mock-server/sales-social/server.d.ts.map +1 -1
  47. package/dist/lib/mock-server/sales-social/server.js +64 -4
  48. package/dist/lib/mock-server/sales-social/server.js.map +1 -1
  49. package/dist/lib/mock-server/scenario.d.ts +97 -0
  50. package/dist/lib/mock-server/scenario.d.ts.map +1 -0
  51. package/dist/lib/mock-server/scenario.js +464 -0
  52. package/dist/lib/mock-server/scenario.js.map +1 -0
  53. package/dist/lib/mock-server/signal-marketplace/server.d.ts +2 -0
  54. package/dist/lib/mock-server/signal-marketplace/server.d.ts.map +1 -1
  55. package/dist/lib/mock-server/signal-marketplace/server.js +29 -1
  56. package/dist/lib/mock-server/signal-marketplace/server.js.map +1 -1
  57. package/dist/lib/mock-server/sponsored-intelligence/server.d.ts +2 -0
  58. package/dist/lib/mock-server/sponsored-intelligence/server.d.ts.map +1 -1
  59. package/dist/lib/mock-server/sponsored-intelligence/server.js +47 -9
  60. package/dist/lib/mock-server/sponsored-intelligence/server.js.map +1 -1
  61. package/dist/lib/protocols/index.d.ts +4 -2
  62. package/dist/lib/protocols/index.d.ts.map +1 -1
  63. package/dist/lib/protocols/index.js +10 -3
  64. package/dist/lib/protocols/index.js.map +1 -1
  65. package/dist/lib/registry/index.d.ts +42 -16
  66. package/dist/lib/registry/index.d.ts.map +1 -1
  67. package/dist/lib/registry/index.js +191 -24
  68. package/dist/lib/registry/index.js.map +1 -1
  69. package/dist/lib/registry/types.d.ts +39 -8
  70. package/dist/lib/registry/types.d.ts.map +1 -1
  71. package/dist/lib/registry/types.generated.d.ts +2873 -699
  72. package/dist/lib/registry/types.generated.d.ts.map +1 -1
  73. package/dist/lib/registry/types.generated.js +2 -2
  74. package/dist/lib/registry/types.generated.js.map +1 -1
  75. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  76. package/dist/lib/server/a2a-adapter.d.ts +3 -1
  77. package/dist/lib/server/a2a-adapter.d.ts.map +1 -1
  78. package/dist/lib/server/a2a-adapter.js +11 -2
  79. package/dist/lib/server/a2a-adapter.js.map +1 -1
  80. package/dist/lib/server/adcp-server.js +32 -0
  81. package/dist/lib/server/adcp-server.js.map +1 -1
  82. package/dist/lib/server/create-adcp-server.d.ts +12 -6
  83. package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
  84. package/dist/lib/server/create-adcp-server.js +72 -11
  85. package/dist/lib/server/create-adcp-server.js.map +1 -1
  86. package/dist/lib/server/decisioning/account.d.ts +17 -17
  87. package/dist/lib/server/decisioning/account.d.ts.map +1 -1
  88. package/dist/lib/server/decisioning/account.js.map +1 -1
  89. package/dist/lib/server/decisioning/buyer-agent.d.ts +27 -10
  90. package/dist/lib/server/decisioning/buyer-agent.d.ts.map +1 -1
  91. package/dist/lib/server/decisioning/buyer-agent.js +25 -7
  92. package/dist/lib/server/decisioning/buyer-agent.js.map +1 -1
  93. package/dist/lib/server/decisioning/capabilities.d.ts +35 -7
  94. package/dist/lib/server/decisioning/capabilities.d.ts.map +1 -1
  95. package/dist/lib/server/decisioning/errors-typed.d.ts +18 -16
  96. package/dist/lib/server/decisioning/errors-typed.d.ts.map +1 -1
  97. package/dist/lib/server/decisioning/errors-typed.js +26 -24
  98. package/dist/lib/server/decisioning/errors-typed.js.map +1 -1
  99. package/dist/lib/server/decisioning/index.d.ts +1 -1
  100. package/dist/lib/server/decisioning/index.d.ts.map +1 -1
  101. package/dist/lib/server/decisioning/index.js +4 -2
  102. package/dist/lib/server/decisioning/index.js.map +1 -1
  103. package/dist/lib/server/decisioning/platform-helpers.d.ts +3 -2
  104. package/dist/lib/server/decisioning/platform-helpers.d.ts.map +1 -1
  105. package/dist/lib/server/decisioning/platform-helpers.js +3 -2
  106. package/dist/lib/server/decisioning/platform-helpers.js.map +1 -1
  107. package/dist/lib/server/decisioning/platform.d.ts +27 -10
  108. package/dist/lib/server/decisioning/platform.d.ts.map +1 -1
  109. package/dist/lib/server/decisioning/platform.js.map +1 -1
  110. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +14 -10
  111. package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
  112. package/dist/lib/server/decisioning/runtime/from-platform.js +374 -59
  113. package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
  114. package/dist/lib/server/decisioning/runtime/validate-platform.d.ts.map +1 -1
  115. package/dist/lib/server/decisioning/runtime/validate-platform.js +3 -8
  116. package/dist/lib/server/decisioning/runtime/validate-platform.js.map +1 -1
  117. package/dist/lib/server/decisioning/specialisms/sponsored-intelligence.d.ts +9 -11
  118. package/dist/lib/server/decisioning/specialisms/sponsored-intelligence.d.ts.map +1 -1
  119. package/dist/lib/server/decisioning/specialisms/sponsored-intelligence.js +9 -11
  120. package/dist/lib/server/decisioning/specialisms/sponsored-intelligence.js.map +1 -1
  121. package/dist/lib/server/operational-platform.d.ts +6 -8
  122. package/dist/lib/server/operational-platform.d.ts.map +1 -1
  123. package/dist/lib/server/operational-platform.js +4 -6
  124. package/dist/lib/server/operational-platform.js.map +1 -1
  125. package/dist/lib/server/test-controller-bridge.d.ts +14 -14
  126. package/dist/lib/server/test-controller-bridge.d.ts.map +1 -1
  127. package/dist/lib/server/test-controller-bridge.js +16 -16
  128. package/dist/lib/server/test-controller-bridge.js.map +1 -1
  129. package/dist/lib/server/test-controller.d.ts +31 -9
  130. package/dist/lib/server/test-controller.d.ts.map +1 -1
  131. package/dist/lib/server/test-controller.js +106 -54
  132. package/dist/lib/server/test-controller.js.map +1 -1
  133. package/dist/lib/signing/canonicalize.d.ts +0 -53
  134. package/dist/lib/signing/canonicalize.d.ts.map +1 -1
  135. package/dist/lib/signing/canonicalize.js +1 -33
  136. package/dist/lib/signing/canonicalize.js.map +1 -1
  137. package/dist/lib/signing/client.d.ts +5 -5
  138. package/dist/lib/signing/client.d.ts.map +1 -1
  139. package/dist/lib/signing/client.js +1 -10
  140. package/dist/lib/signing/client.js.map +1 -1
  141. package/dist/lib/signing/errors.d.ts +0 -11
  142. package/dist/lib/signing/errors.d.ts.map +1 -1
  143. package/dist/lib/signing/errors.js +1 -11
  144. package/dist/lib/signing/errors.js.map +1 -1
  145. package/dist/lib/signing/jwks-helpers.d.ts +2 -4
  146. package/dist/lib/signing/jwks-helpers.d.ts.map +1 -1
  147. package/dist/lib/signing/jwks-helpers.js +9 -0
  148. package/dist/lib/signing/jwks-helpers.js.map +1 -1
  149. package/dist/lib/signing/provider.d.ts +11 -10
  150. package/dist/lib/signing/provider.d.ts.map +1 -1
  151. package/dist/lib/signing/request-context.d.ts +8 -11
  152. package/dist/lib/signing/request-context.d.ts.map +1 -1
  153. package/dist/lib/signing/request-context.js +7 -10
  154. package/dist/lib/signing/request-context.js.map +1 -1
  155. package/dist/lib/signing/server.d.ts +3 -4
  156. package/dist/lib/signing/server.d.ts.map +1 -1
  157. package/dist/lib/signing/server.js +1 -9
  158. package/dist/lib/signing/server.js.map +1 -1
  159. package/dist/lib/signing/signer-async.d.ts +2 -8
  160. package/dist/lib/signing/signer-async.d.ts.map +1 -1
  161. package/dist/lib/signing/signer-async.js +0 -12
  162. package/dist/lib/signing/signer-async.js.map +1 -1
  163. package/dist/lib/signing/signer.d.ts +4 -111
  164. package/dist/lib/signing/signer.d.ts.map +1 -1
  165. package/dist/lib/signing/signer.js +2 -98
  166. package/dist/lib/signing/signer.js.map +1 -1
  167. package/dist/lib/signing/testing.d.ts +10 -10
  168. package/dist/lib/signing/testing.d.ts.map +1 -1
  169. package/dist/lib/signing/testing.js +6 -13
  170. package/dist/lib/signing/testing.js.map +1 -1
  171. package/dist/lib/signing/types.d.ts +0 -36
  172. package/dist/lib/signing/types.d.ts.map +1 -1
  173. package/dist/lib/signing/types.js +1 -37
  174. package/dist/lib/signing/types.js.map +1 -1
  175. package/dist/lib/testing/agent-tester.d.ts +1 -0
  176. package/dist/lib/testing/agent-tester.d.ts.map +1 -1
  177. package/dist/lib/testing/agent-tester.js.map +1 -1
  178. package/dist/lib/testing/client.d.ts +1 -1
  179. package/dist/lib/testing/client.d.ts.map +1 -1
  180. package/dist/lib/testing/client.js +4 -2
  181. package/dist/lib/testing/client.js.map +1 -1
  182. package/dist/lib/testing/compliance/comply.d.ts +8 -0
  183. package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
  184. package/dist/lib/testing/compliance/comply.js +98 -7
  185. package/dist/lib/testing/compliance/comply.js.map +1 -1
  186. package/dist/lib/testing/compliance/spec-conformance.d.ts +6 -6
  187. package/dist/lib/testing/compliance/spec-conformance.d.ts.map +1 -1
  188. package/dist/lib/testing/compliance/spec-conformance.js +6 -6
  189. package/dist/lib/testing/compliance/spec-conformance.js.map +1 -1
  190. package/dist/lib/testing/compliance/summary.d.ts +5 -0
  191. package/dist/lib/testing/compliance/summary.d.ts.map +1 -1
  192. package/dist/lib/testing/compliance/summary.js +17 -0
  193. package/dist/lib/testing/compliance/summary.js.map +1 -1
  194. package/dist/lib/testing/comply-controller.d.ts +19 -0
  195. package/dist/lib/testing/comply-controller.d.ts.map +1 -1
  196. package/dist/lib/testing/comply-controller.js +11 -8
  197. package/dist/lib/testing/comply-controller.js.map +1 -1
  198. package/dist/lib/testing/index.d.ts +4 -3
  199. package/dist/lib/testing/index.d.ts.map +1 -1
  200. package/dist/lib/testing/index.js +13 -1
  201. package/dist/lib/testing/index.js.map +1 -1
  202. package/dist/lib/testing/storyboard/canonical-format-satisfaction.d.ts +4 -0
  203. package/dist/lib/testing/storyboard/canonical-format-satisfaction.d.ts.map +1 -0
  204. package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +881 -0
  205. package/dist/lib/testing/storyboard/canonical-format-satisfaction.js.map +1 -0
  206. package/dist/lib/testing/storyboard/compliance.d.ts +6 -0
  207. package/dist/lib/testing/storyboard/compliance.d.ts.map +1 -1
  208. package/dist/lib/testing/storyboard/compliance.js +8 -4
  209. package/dist/lib/testing/storyboard/compliance.js.map +1 -1
  210. package/dist/lib/testing/storyboard/index.d.ts +2 -1
  211. package/dist/lib/testing/storyboard/index.d.ts.map +1 -1
  212. package/dist/lib/testing/storyboard/index.js +9 -1
  213. package/dist/lib/testing/storyboard/index.js.map +1 -1
  214. package/dist/lib/testing/storyboard/loader.d.ts +3 -2
  215. package/dist/lib/testing/storyboard/loader.d.ts.map +1 -1
  216. package/dist/lib/testing/storyboard/loader.js +73 -2
  217. package/dist/lib/testing/storyboard/loader.js.map +1 -1
  218. package/dist/lib/testing/storyboard/path.d.ts +21 -0
  219. package/dist/lib/testing/storyboard/path.d.ts.map +1 -1
  220. package/dist/lib/testing/storyboard/path.js +86 -0
  221. package/dist/lib/testing/storyboard/path.js.map +1 -1
  222. package/dist/lib/testing/storyboard/rate-limit-trip.d.ts +92 -0
  223. package/dist/lib/testing/storyboard/rate-limit-trip.d.ts.map +1 -0
  224. package/dist/lib/testing/storyboard/rate-limit-trip.js +276 -0
  225. package/dist/lib/testing/storyboard/rate-limit-trip.js.map +1 -0
  226. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  227. package/dist/lib/testing/storyboard/runner.js +361 -28
  228. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  229. package/dist/lib/testing/storyboard/seeding.d.ts +5 -4
  230. package/dist/lib/testing/storyboard/seeding.d.ts.map +1 -1
  231. package/dist/lib/testing/storyboard/seeding.js +23 -3
  232. package/dist/lib/testing/storyboard/seeding.js.map +1 -1
  233. package/dist/lib/testing/storyboard/types.d.ts +108 -20
  234. package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
  235. package/dist/lib/testing/storyboard/types.js +1 -0
  236. package/dist/lib/testing/storyboard/types.js.map +1 -1
  237. package/dist/lib/testing/storyboard/validations.d.ts +18 -0
  238. package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
  239. package/dist/lib/testing/storyboard/validations.js +238 -33
  240. package/dist/lib/testing/storyboard/validations.js.map +1 -1
  241. package/dist/lib/testing/test-controller.d.ts +17 -25
  242. package/dist/lib/testing/test-controller.d.ts.map +1 -1
  243. package/dist/lib/testing/test-controller.js.map +1 -1
  244. package/dist/lib/testing/types.d.ts +13 -1
  245. package/dist/lib/testing/types.d.ts.map +1 -1
  246. package/dist/lib/types/check-governance.d.ts +1 -1
  247. package/dist/lib/types/comply-test-controller.d.ts +243 -3
  248. package/dist/lib/types/core.generated.d.ts +261 -21
  249. package/dist/lib/types/core.generated.d.ts.map +1 -1
  250. package/dist/lib/types/core.generated.js +1 -1
  251. package/dist/lib/types/create-media-buy.d.ts +107 -3
  252. package/dist/lib/types/error-codes.d.ts +2 -2
  253. package/dist/lib/types/get-adcp-capabilities.d.ts +1 -1
  254. package/dist/lib/types/get-media-buys.d.ts +107 -3
  255. package/dist/lib/types/get-plan-audit-logs.d.ts +1 -1
  256. package/dist/lib/types/get-products.d.ts +104 -3
  257. package/dist/lib/types/inline-enums.generated.d.ts +27 -17
  258. package/dist/lib/types/inline-enums.generated.d.ts.map +1 -1
  259. package/dist/lib/types/inline-enums.generated.js +39 -28
  260. package/dist/lib/types/inline-enums.generated.js.map +1 -1
  261. package/dist/lib/types/manifest.generated.d.ts +7 -4
  262. package/dist/lib/types/manifest.generated.d.ts.map +1 -1
  263. package/dist/lib/types/manifest.generated.js +2 -2
  264. package/dist/lib/types/manifest.generated.js.map +1 -1
  265. package/dist/lib/types/report-plan-outcome.d.ts +1 -1
  266. package/dist/lib/types/schemas.generated.d.ts +714 -193
  267. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  268. package/dist/lib/types/schemas.generated.js +194 -79
  269. package/dist/lib/types/schemas.generated.js.map +1 -1
  270. package/dist/lib/types/sync-plans.d.ts +1 -1
  271. package/dist/lib/types/tools.generated.d.ts +331 -28
  272. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  273. package/dist/lib/types/update-media-buy.d.ts +107 -3
  274. package/dist/lib/types/v3-1-beta/tools.generated.d.ts +20 -0
  275. package/dist/lib/types/v3-1-beta/tools.generated.d.ts.map +1 -1
  276. package/dist/lib/upstream-recorder/constants.d.ts +2 -0
  277. package/dist/lib/upstream-recorder/constants.d.ts.map +1 -0
  278. package/dist/lib/upstream-recorder/constants.js +5 -0
  279. package/dist/lib/upstream-recorder/constants.js.map +1 -0
  280. package/dist/lib/upstream-recorder/index.d.ts +20 -10
  281. package/dist/lib/upstream-recorder/index.d.ts.map +1 -1
  282. package/dist/lib/upstream-recorder/index.js +21 -10
  283. package/dist/lib/upstream-recorder/index.js.map +1 -1
  284. package/dist/lib/upstream-recorder/recorder.d.ts +65 -0
  285. package/dist/lib/upstream-recorder/recorder.d.ts.map +1 -1
  286. package/dist/lib/upstream-recorder/recorder.js +500 -47
  287. package/dist/lib/upstream-recorder/recorder.js.map +1 -1
  288. package/dist/lib/upstream-recorder/types.d.ts +109 -13
  289. package/dist/lib/upstream-recorder/types.d.ts.map +1 -1
  290. package/dist/lib/upstream-recorder/types.js.map +1 -1
  291. package/dist/lib/utils/adcp-version-config.d.ts +1 -0
  292. package/dist/lib/utils/adcp-version-config.d.ts.map +1 -1
  293. package/dist/lib/utils/adcp-version-config.js +21 -0
  294. package/dist/lib/utils/adcp-version-config.js.map +1 -1
  295. package/dist/lib/utils/capability-rollups.d.ts +5 -5
  296. package/dist/lib/utils/capability-rollups.d.ts.map +1 -1
  297. package/dist/lib/utils/capability-rollups.js +1 -1
  298. package/dist/lib/utils/capability-rollups.js.map +1 -1
  299. package/dist/lib/utils/json-depth.d.ts +2 -0
  300. package/dist/lib/utils/json-depth.d.ts.map +1 -0
  301. package/dist/lib/utils/json-depth.js +5 -0
  302. package/dist/lib/utils/json-depth.js.map +1 -0
  303. package/dist/lib/utils/media-buy-delivery-notification-builders.d.ts +1 -1
  304. package/dist/lib/utils/media-buy-delivery-notification-builders.d.ts.map +1 -1
  305. package/dist/lib/utils/preview-creative-builders.d.ts +1 -1
  306. package/dist/lib/utils/preview-creative-builders.d.ts.map +1 -1
  307. package/dist/lib/utils/redact-secrets.d.ts +13 -2
  308. package/dist/lib/utils/redact-secrets.d.ts.map +1 -1
  309. package/dist/lib/utils/redact-secrets.js +40 -13
  310. package/dist/lib/utils/redact-secrets.js.map +1 -1
  311. package/dist/lib/utils/response-schemas.d.ts +1 -0
  312. package/dist/lib/utils/response-schemas.d.ts.map +1 -1
  313. package/dist/lib/utils/response-schemas.js +15 -0
  314. package/dist/lib/utils/response-schemas.js.map +1 -1
  315. package/dist/lib/utils/response-unwrapper.d.ts +2 -1
  316. package/dist/lib/utils/response-unwrapper.d.ts.map +1 -1
  317. package/dist/lib/utils/response-unwrapper.js +11 -3
  318. package/dist/lib/utils/response-unwrapper.js.map +1 -1
  319. package/dist/lib/utils/tool-request-schemas.d.ts +31 -1
  320. package/dist/lib/utils/tool-request-schemas.d.ts.map +1 -1
  321. package/dist/lib/v2/format-schema/fetch.d.ts +13 -5
  322. package/dist/lib/v2/format-schema/fetch.d.ts.map +1 -1
  323. package/dist/lib/v2/format-schema/fetch.js +27 -16
  324. package/dist/lib/v2/format-schema/fetch.js.map +1 -1
  325. package/dist/lib/v2/format-schema/index.d.ts +13 -11
  326. package/dist/lib/v2/format-schema/index.d.ts.map +1 -1
  327. package/dist/lib/v2/format-schema/index.js +19 -12
  328. package/dist/lib/v2/format-schema/index.js.map +1 -1
  329. package/dist/lib/v2/format-schema/resolver.d.ts +71 -0
  330. package/dist/lib/v2/format-schema/resolver.d.ts.map +1 -0
  331. package/dist/lib/v2/format-schema/resolver.js +284 -0
  332. package/dist/lib/v2/format-schema/resolver.js.map +1 -0
  333. package/dist/lib/v2/format-schema/sandbox-refs.d.ts +6 -0
  334. package/dist/lib/v2/format-schema/sandbox-refs.d.ts.map +1 -1
  335. package/dist/lib/v2/format-schema/sandbox-refs.js +36 -15
  336. package/dist/lib/v2/format-schema/sandbox-refs.js.map +1 -1
  337. package/dist/lib/validation/schema-loader.d.ts.map +1 -1
  338. package/dist/lib/validation/schema-loader.js +48 -3
  339. package/dist/lib/validation/schema-loader.js.map +1 -1
  340. package/dist/lib/version.d.ts +3 -3
  341. package/dist/lib/version.js +3 -3
  342. package/docs/guides/BUILD-AN-AGENT.md +7 -7
  343. package/docs/guides/CANONICAL-REFERENCE-RESOLVER.md +75 -0
  344. package/docs/llms.txt +37 -8
  345. package/examples/README.md +29 -16
  346. package/examples/hello_creative_adapter_ad_server.ts +8 -2
  347. package/examples/hello_seller_adapter_guaranteed.ts +26 -18
  348. package/examples/hello_seller_adapter_multi_tenant.ts +6 -6
  349. package/examples/hello_seller_adapter_social.ts +80 -4
  350. package/examples/hello_si_adapter_brand.ts +10 -21
  351. package/examples/hello_signals_adapter_marketplace.ts +184 -9
  352. package/examples/proxy-seller-snap/README.md +47 -0
  353. package/examples/proxy-seller-snap/index.ts +321 -0
  354. package/package.json +19 -4
  355. package/skills/build-creative-agent/SKILL.md +1 -15
  356. package/skills/build-decisioning-platform/SKILL.md +6 -1
  357. package/skills/build-seller-agent/SKILL.md +5 -2
  358. package/skills/build-si-agent/SKILL.md +2 -2
  359. package/skills/call-adcp-agent/SKILL.md +4 -1
  360. package/dist/lib/signing/response-verifier.d.ts +0 -105
  361. package/dist/lib/signing/response-verifier.d.ts.map +0 -1
  362. package/dist/lib/signing/response-verifier.js +0 -271
  363. package/dist/lib/signing/response-verifier.js.map +0 -1
@@ -33,6 +33,8 @@ import {
33
33
  type AccountStore,
34
34
  type Account,
35
35
  type BuyerAgent,
36
+ type BuyerAgentBillingMode,
37
+ type BuyerAgentStatus,
36
38
  type CachedBuyerAgentRegistry,
37
39
  } from '@adcp/sdk/server';
38
40
  import type { GetSignalsResponse, ActivateSignalRequest, ActivateSignalSuccess } from '@adcp/sdk/types';
@@ -283,6 +285,114 @@ const ONBOARDING_LEDGER = new Map<string, BuyerAgent>([
283
285
  ],
284
286
  ]);
285
287
 
288
+ const SEEDED_BUYER_AGENT_OVERLAY = new Map<string, BuyerAgent>();
289
+
290
+ const BUYER_AGENT_BILLING_MODES = new Set<BuyerAgentBillingMode>(['operator', 'agent', 'advertiser']);
291
+ const BUYER_AGENT_STATUSES = new Set<BuyerAgentStatus>(['active', 'suspended', 'blocked']);
292
+
293
+ function readRequestAccountRef(input: Record<string, unknown> | undefined): Record<string, unknown> | undefined {
294
+ const topLevel = input?.['account'];
295
+ if (topLevel != null && typeof topLevel === 'object') return topLevel as Record<string, unknown>;
296
+ const context = input?.['context'];
297
+ if (context != null && typeof context === 'object') {
298
+ const contextAccount = (context as { account?: unknown }).account;
299
+ if (contextAccount != null && typeof contextAccount === 'object') return contextAccount as Record<string, unknown>;
300
+ }
301
+ return undefined;
302
+ }
303
+
304
+ function readSessionId(input: Record<string, unknown> | undefined): string | undefined {
305
+ const context = input?.['context'];
306
+ if (context == null || typeof context !== 'object') return undefined;
307
+ const sessionId = (context as { session_id?: unknown }).session_id;
308
+ return typeof sessionId === 'string' && sessionId.length > 0 ? sessionId : undefined;
309
+ }
310
+
311
+ function accountScope(ref: Record<string, unknown> | undefined): string | undefined {
312
+ if (!ref) return undefined;
313
+ const accountId = ref['account_id'];
314
+ if (typeof accountId === 'string' && accountId.length > 0) return `account_id:${accountId}`;
315
+ const brand = ref['brand'];
316
+ const brandDomain = brand != null && typeof brand === 'object' ? (brand as { domain?: unknown }).domain : undefined;
317
+ const operator = ref['operator'];
318
+ const sandbox = ref['sandbox'];
319
+ if (typeof brandDomain !== 'string' && typeof operator !== 'string' && typeof sandbox !== 'boolean') {
320
+ return undefined;
321
+ }
322
+ return JSON.stringify({
323
+ ...(typeof brandDomain === 'string' && { brand_domain: brandDomain }),
324
+ ...(typeof operator === 'string' && { operator }),
325
+ ...(typeof sandbox === 'boolean' && { sandbox }),
326
+ });
327
+ }
328
+
329
+ function buyerAgentOverlayKey(
330
+ agentUrl: string,
331
+ input: Record<string, unknown> | undefined,
332
+ ref: Record<string, unknown> | undefined
333
+ ): string | undefined {
334
+ const parts: string[] = [];
335
+ const sessionId = readSessionId(input);
336
+ if (sessionId) parts.push(`session:${sessionId}`);
337
+ const scope = accountScope(ref);
338
+ if (scope) parts.push(`account:${scope}`);
339
+ return parts.length > 0 ? `${parts.join('|')}:agent:${agentUrl}` : undefined;
340
+ }
341
+
342
+ function overlayBuyerAgent(
343
+ base: BuyerAgent,
344
+ input: Record<string, unknown> | undefined,
345
+ ref: Record<string, unknown> | undefined
346
+ ): BuyerAgent {
347
+ const key = buyerAgentOverlayKey(base.agent_url, input, ref);
348
+ const seeded = key ? SEEDED_BUYER_AGENT_OVERLAY.get(key) : undefined;
349
+ if (!seeded) {
350
+ return base;
351
+ }
352
+ return {
353
+ ...base,
354
+ ...seeded,
355
+ billing_capabilities: new Set(seeded.billing_capabilities),
356
+ };
357
+ }
358
+
359
+ function seedBuyerAgentOverlay(
360
+ params: {
361
+ agent_url: string;
362
+ display_name?: string;
363
+ status?: BuyerAgentStatus;
364
+ billing_capabilities?: BuyerAgentBillingMode[];
365
+ sandbox_only?: boolean;
366
+ },
367
+ input: Record<string, unknown>
368
+ ): void {
369
+ const existing =
370
+ Array.from(ONBOARDING_LEDGER.values()).find(agent => agent.agent_url === params.agent_url) ??
371
+ Array.from(SEEDED_BUYER_AGENT_OVERLAY.values()).find(agent => agent.agent_url === params.agent_url);
372
+ const key = buyerAgentOverlayKey(params.agent_url, input, readRequestAccountRef(input));
373
+ if (!key) {
374
+ throw new AdcpError('INVALID_REQUEST', {
375
+ message: 'seed_buyer_agent requires a session_id or account scope for this example overlay.',
376
+ });
377
+ }
378
+ const modes = (params.billing_capabilities ?? Array.from(existing?.billing_capabilities ?? ['operator'])).filter(
379
+ (mode): mode is BuyerAgentBillingMode => BUYER_AGENT_BILLING_MODES.has(mode as BuyerAgentBillingMode)
380
+ );
381
+ const status =
382
+ params.status && BUYER_AGENT_STATUSES.has(params.status) ? params.status : (existing?.status ?? 'active');
383
+
384
+ SEEDED_BUYER_AGENT_OVERLAY.set(key, {
385
+ agent_url: params.agent_url,
386
+ display_name: params.display_name ?? existing?.display_name ?? 'Compliance seeded buyer agent',
387
+ status,
388
+ billing_capabilities: new Set(modes.length > 0 ? modes : ['operator']),
389
+ sandbox_only: params.sandbox_only ?? existing?.sandbox_only ?? true,
390
+ });
391
+ // Mutating commercial state must purge cached registry entries; otherwise a
392
+ // just-suspended test buyer could remain active until the TTL expires.
393
+ agentRegistry.clear();
394
+ }
395
+
286
396
  /**
287
397
  * `bearerOnly` because this example authenticates via `verifyApiKey`.
288
398
  * Sellers wiring `verifySignatureAsAuthenticator` swap to `signingOnly`
@@ -293,7 +403,7 @@ const ONBOARDING_LEDGER = new Map<string, BuyerAgent>([
293
403
  * onboarding ledger. `invalidate(credential)` purges a stale entry when
294
404
  * the seller mutates an agent's record (status flip, etc.).
295
405
  */
296
- const agentRegistry: CachedBuyerAgentRegistry = BuyerAgentRegistry.cached(
406
+ const baseAgentRegistry: CachedBuyerAgentRegistry = BuyerAgentRegistry.cached(
297
407
  BuyerAgentRegistry.bearerOnly({
298
408
  resolveByCredential: async credential => {
299
409
  // bearerOnly receives every credential kind; MUST kind-discriminate
@@ -305,6 +415,16 @@ const agentRegistry: CachedBuyerAgentRegistry = BuyerAgentRegistry.cached(
305
415
  { ttlSeconds: 60 }
306
416
  );
307
417
 
418
+ const agentRegistry: CachedBuyerAgentRegistry = {
419
+ async resolve(authInfo) {
420
+ const base = await baseAgentRegistry.resolve(authInfo);
421
+ if (!base) return base;
422
+ return overlayBuyerAgent(base, authInfo.input, readRequestAccountRef(authInfo.input));
423
+ },
424
+ invalidate: credential => baseAgentRegistry.invalidate(credential),
425
+ clear: () => baseAgentRegistry.clear(),
426
+ };
427
+
308
428
  // ---------------------------------------------------------------------------
309
429
  // AdCP-side adapter — typed against SignalsPlatform.
310
430
  // ---------------------------------------------------------------------------
@@ -358,9 +478,12 @@ class SignalMarketplaceAdapter implements DecisioningPlatform<Record<string, nev
358
478
  * Buyer-agent registry — framework runs `agentRegistry.resolve(authInfo)`
359
479
  * once per request and threads the resolved record through `ctx.agent`
360
480
  * to specialism handlers AND to `accounts.resolve` (below). When the
361
- * resolved agent's `status` is `suspended` / `blocked`, the framework
362
- * rejects the request with PERMISSION_DENIED before invoking any
363
- * handler adopters don't reimplement that gate.
481
+ * resolved agent's durable `status` is `suspended` / `blocked`, the
482
+ * framework rejects the request with the AdCP 3.1 `AGENT_SUSPENDED` /
483
+ * `AGENT_BLOCKED` codes before invoking any handler. The scoped
484
+ * compliance overlay below mirrors that behavior inside `accounts.resolve`
485
+ * so `seed_buyer_agent` can vary test-only state without mutating the
486
+ * process-wide onboarding ledger.
364
487
  */
365
488
  agentRegistry = agentRegistry;
366
489
 
@@ -371,20 +494,61 @@ class SignalMarketplaceAdapter implements DecisioningPlatform<Record<string, nev
371
494
  * tenant resolution against the durable buyer-agent identity here
372
495
  * rather than re-deriving from the credential. */
373
496
  resolve: async (ref, ctx) => {
374
- if (!ref) return null;
497
+ let effectiveRef = ref;
498
+ if (!effectiveRef) {
499
+ const inputAccount = readRequestAccountRef(ctx?.input as Record<string, unknown> | undefined);
500
+ // TEST-ONLY: comply_test_controller discovery and account-less
501
+ // controller calls resolve through this auth-derived path. When the
502
+ // caller supplied an account in the controller payload/context, use
503
+ // it; otherwise fall back to the single operator this worked example
504
+ // uses for the conformance harness. Production sellers replace this
505
+ // with a real principal → sandbox-account lookup.
506
+ if (inputAccount != null && 'account_id' in inputAccount) return null;
507
+ const inputBrand = inputAccount?.['brand'];
508
+ const inputBrandDomain =
509
+ inputBrand != null && typeof inputBrand === 'object'
510
+ ? (inputBrand as { domain?: unknown }).domain
511
+ : undefined;
512
+ const inputOperator = inputAccount?.['operator'];
513
+ const inputSandbox = inputAccount?.['sandbox'];
514
+ effectiveRef =
515
+ typeof inputOperator === 'string'
516
+ ? {
517
+ brand: { domain: typeof inputBrandDomain === 'string' ? inputBrandDomain : 'acmeoutdoor.example' },
518
+ operator: inputOperator,
519
+ ...(typeof inputSandbox === 'boolean' && { sandbox: inputSandbox }),
520
+ }
521
+ : {
522
+ brand: { domain: 'acmeoutdoor.example' },
523
+ operator: 'pinnacle-agency.example',
524
+ sandbox: true,
525
+ };
526
+ }
527
+ if (!effectiveRef) return null;
375
528
  // AccountReference discriminated union: `{ account_id }` post-sync,
376
529
  // or `{ brand, operator, sandbox? }` on initial discovery. Mock has
377
530
  // no account_id index; SWAP: production keeps an account_id →
378
531
  // operator_id index populated during list_accounts.
379
- if ('account_id' in ref) return null;
380
- const adcpOperator = ref.operator;
532
+ if ('account_id' in effectiveRef) return null;
533
+ const adcpOperator = effectiveRef.operator;
381
534
  if (!adcpOperator) return null;
382
535
  // Optional: gate the operator on the buyer agent's allowed_brands /
383
536
  // billing_capabilities. Sellers who don't cross-check operator vs.
384
537
  // agent here let any onboarded agent operate on any operator —
385
538
  // legitimate for some marketplaces, a leak for others.
386
- const buyerAgent = ctx?.agent;
387
- void buyerAgent; // demonstration site — wire your own checks here.
539
+ const buyerAgent =
540
+ ctx?.agent && ctx.input
541
+ ? overlayBuyerAgent(ctx.agent, ctx.input, effectiveRef as Record<string, unknown>)
542
+ : ctx?.agent;
543
+ if (buyerAgent?.status === 'suspended' || buyerAgent?.status === 'blocked') {
544
+ throw new AdcpError(buyerAgent.status === 'suspended' ? 'AGENT_SUSPENDED' : 'AGENT_BLOCKED', {
545
+ message:
546
+ buyerAgent.status === 'suspended'
547
+ ? 'Buyer agent is suspended. Contact the seller to restore access.'
548
+ : 'Buyer agent is blocked.',
549
+ recovery: 'terminal',
550
+ });
551
+ }
388
552
  const operatorId = await upstream.lookupOperator(adcpOperator);
389
553
  if (!operatorId) return null;
390
554
  return {
@@ -392,6 +556,7 @@ class SignalMarketplaceAdapter implements DecisioningPlatform<Record<string, nev
392
556
  name: adcpOperator,
393
557
  status: 'active',
394
558
  operator: adcpOperator,
559
+ mode: 'sandbox',
395
560
  ctx_metadata: { operator_id: operatorId },
396
561
  // The upstream here is the AdCP mock-server. Every account it
397
562
  // returns is a sandbox account by definition. Production
@@ -540,6 +705,16 @@ serve(
540
705
  // account's `mode` is `'sandbox'` or `'mock'` (per `Account.mode`,
541
706
  // AdCP 6.7+). See `docs/proposals/lifecycle-state-and-sandbox-authority.md`.
542
707
  complyTest: {
708
+ seed: {
709
+ // Test-only commercial-state setup for AdCP 3.1 storyboards that
710
+ // declare `fixtures.buyer_agents[]`. This overlays the static
711
+ // onboarding ledger by agent_url, so the existing bearer credential
712
+ // still authenticates normally while the storyboard can vary status,
713
+ // sandbox_only, or billing_capabilities for the resolved buyer agent.
714
+ buyer_agent: (params, ctx) => {
715
+ seedBuyerAgentOverlay(params, ctx.input);
716
+ },
717
+ },
543
718
  // Adapter resolves principal from auth context. The same string
544
719
  // MUST be returned by both record-time (runWithPrincipal) and
545
720
  // query-time — mismatch returns zero per cross-tenant isolation.
@@ -0,0 +1,47 @@
1
+ # Proxy Seller Snap Example
2
+
3
+ This is the fork target for a seller whose AdCP read path proxies an upstream ads platform: Snap, Meta, TikTok, Pinterest, LinkedIn, Google, Amazon, Reddit, Spotify, Criteo, CitrusAd, FlashTalking, UniversalAds, and similar DSP or walled-garden adapters.
4
+
5
+ ## Diagnostic
6
+
7
+ If `get_products`, `list_creatives`, `list_property_lists`, or another read tool calls the upstream platform API directly, `comply_test_controller.seed_product` and `seed_creative` are otherwise dead writes. The seed lands in your local test controller, but your read handler asks Snap for products or creatives and never sees it.
8
+
9
+ Wire `TestControllerBridge` for storyboard conformance. The handler still runs first; the SDK merges seeded fixtures into sandbox responses after the upstream call succeeds. That proves AdCP wire conformance, not live Snap adapter health.
10
+
11
+ ## What This Example Wires
12
+
13
+ - `TestControllerBridge<SnapAccount>` through `bridgeFromSessionStore`.
14
+ - Resolved-account session loading: `loadSession: (_input, ctx) => sessionStore.loadForAccount(ctx.account)`.
15
+ - Seed selectors for `get_products`, `list_creatives`, and property-list governance reads.
16
+ - `resolveAccount` as the trust boundary. The bridge keys on the resolved `ctx.account`, not on caller-supplied request fields.
17
+ - Optional `comply_test_controller` registration gated by `ADCP_SANDBOX=1`.
18
+
19
+ ## Verification Scope
20
+
21
+ Bridge-augmented storyboard passes are wire-conformance evidence. They do not prove your Snap OAuth token, account lookup, product catalog, or creative library calls are healthy. Pair this with a live-OAuth sandbox runner that disables or records bridge participation and asserts real upstream traffic.
22
+
23
+ Run:
24
+
25
+ ```bash
26
+ ADCP_SANDBOX=1 npx tsx examples/proxy-seller-snap/index.ts
27
+ ```
28
+
29
+ Then seed and read with a sandbox account:
30
+
31
+ ```bash
32
+ adcp call http://127.0.0.1:3018/mcp comply_test_controller \
33
+ '{"scenario":"seed_product","params":{"product_id":"snap-storyboard-product","fixture":{"name":"Seeded product"}},"account":{"account_id":"snap_sandbox_acme","sandbox":true}}' \
34
+ --auth sk_snap_proxy_harness_do_not_use_in_prod
35
+
36
+ adcp call http://127.0.0.1:3018/mcp get_products \
37
+ '{"buying_mode":"brief","brief":"outdoor apparel","account":{"account_id":"snap_sandbox_acme","sandbox":true}}' \
38
+ --auth sk_snap_proxy_harness_do_not_use_in_prod
39
+ ```
40
+
41
+ Forking checklist:
42
+
43
+ 1. Replace `emptySnapClient` with real Snap OAuth and Marketing API calls.
44
+ 2. Replace `resolveSnapAccount` with your production account resolver.
45
+ 3. Keep bridge registration limited to sandbox or conformance deployments.
46
+ 4. Keep bridge session reads keyed on the resolved account.
47
+ 5. Add a live-OAuth test that exercises the adapter without relying on `_bridge`-augmented fixtures.
@@ -0,0 +1,321 @@
1
+ /**
2
+ * proxy-seller-snap — fork target for proxy-shaped sellers whose AdCP read
3
+ * path fronts an upstream ads platform instead of a seller-owned datastore.
4
+ *
5
+ * Snap is the concrete shape because it is representative: account resolution
6
+ * maps the buyer's AdCP account to a Snap ad account, read handlers call a
7
+ * Snap-shaped client, and `TestControllerBridge` makes storyboard-seeded
8
+ * fixtures visible on sandbox reads without pretending the adapter's live
9
+ * upstream path is healthy.
10
+ *
11
+ * FORK CHECKLIST
12
+ * 1. Replace `emptySnapClient` with your real upstream OAuth/API client.
13
+ * 2. Replace `resolveSnapAccount` with your production account resolver.
14
+ * 3. Keep `bridgeFromSessionStore` keyed on resolved `ctx.account`.
15
+ * 4. Register `comply_test_controller` only in sandbox/conformance hosts.
16
+ * 5. Add a live-OAuth sandbox runner that proves adapter health without
17
+ * relying on `_bridge`-augmented fixtures.
18
+ *
19
+ * Run locally:
20
+ *
21
+ * ADCP_SANDBOX=1 npx tsx examples/proxy-seller-snap/index.ts
22
+ * adcp call http://127.0.0.1:3018/mcp get_products \
23
+ * '{"buying_mode":"brief","brief":"outdoor apparel","account":{"account_id":"snap_sandbox_acme","sandbox":true}}' \
24
+ * --auth sk_snap_proxy_harness_do_not_use_in_prod
25
+ */
26
+
27
+ import { z } from 'zod';
28
+ import { createAdcpServer } from '@adcp/sdk/server/legacy/v5';
29
+ import {
30
+ AdcpError,
31
+ bridgeFromSessionStore,
32
+ InMemoryStateStore,
33
+ serve,
34
+ verifyApiKey,
35
+ type SeededCreative,
36
+ type TestControllerBridge,
37
+ } from '@adcp/sdk/server';
38
+ import { createComplyController } from '@adcp/sdk/testing';
39
+ import type { AccountReference, GetProductsResponse, PropertyList } from '@adcp/sdk/types';
40
+
41
+ type ValidationMode = 'strict' | 'warn' | 'off';
42
+ type Product = NonNullable<GetProductsResponse['products']>[number];
43
+
44
+ const PORT = Number(process.env['PORT'] ?? 3018);
45
+ const ADCP_AUTH_TOKEN = process.env['ADCP_AUTH_TOKEN'] ?? 'sk_snap_proxy_harness_do_not_use_in_prod';
46
+ const PUBLIC_AGENT_URL = process.env['PUBLIC_AGENT_URL'] ?? `http://127.0.0.1:${PORT}`;
47
+ const DEFAULT_SANDBOX_ACCOUNT_ID = 'snap_sandbox_acme';
48
+
49
+ interface SnapAccount {
50
+ id: string;
51
+ name: string;
52
+ status: 'active' | 'pending_approval' | 'rejected' | 'payment_required' | 'suspended' | 'closed';
53
+ sandbox?: boolean;
54
+ mode?: 'sandbox' | 'live';
55
+ brand?: { domain: string };
56
+ operator?: string;
57
+ ctx_metadata: {
58
+ snap_ad_account_id: string;
59
+ bridge_session_id: string;
60
+ };
61
+ }
62
+
63
+ interface SnapBridgeSession {
64
+ seededProducts: Map<string, Record<string, unknown>>;
65
+ seededCreatives: SeededCreative[];
66
+ seededPropertyLists: PropertyList[];
67
+ }
68
+
69
+ export interface SnapClient {
70
+ listProducts(adAccountId: string): Promise<Product[]>;
71
+ listCreatives(adAccountId: string): Promise<SeededCreative[]>;
72
+ listPropertyLists(adAccountId: string): Promise<PropertyList[]>;
73
+ }
74
+
75
+ export class InMemorySnapSessionStore {
76
+ private readonly sessions = new Map<string, SnapBridgeSession>();
77
+
78
+ loadForAccount(account: SnapAccount): SnapBridgeSession {
79
+ return this.load(account.ctx_metadata.bridge_session_id);
80
+ }
81
+
82
+ load(sessionId: string): SnapBridgeSession {
83
+ let session = this.sessions.get(sessionId);
84
+ if (!session) {
85
+ session = { seededProducts: new Map(), seededCreatives: [], seededPropertyLists: [] };
86
+ this.sessions.set(sessionId, session);
87
+ }
88
+ return session;
89
+ }
90
+
91
+ loadForControllerInput(input: Record<string, unknown>): SnapBridgeSession {
92
+ const accountId = readAccountId(input) ?? DEFAULT_SANDBOX_ACCOUNT_ID;
93
+ return this.load(`snap:${accountId}`);
94
+ }
95
+ }
96
+
97
+ export function createInMemorySnapSessionStore(): InMemorySnapSessionStore {
98
+ return new InMemorySnapSessionStore();
99
+ }
100
+
101
+ const emptySnapClient: SnapClient = {
102
+ // SWAP: production calls Snap Marketing API product/catalog endpoints.
103
+ async listProducts() {
104
+ return [];
105
+ },
106
+ // SWAP: production calls Snap creative library endpoints.
107
+ async listCreatives() {
108
+ return [];
109
+ },
110
+ // SWAP: production calls the upstream governance/list surface you proxy.
111
+ async listPropertyLists() {
112
+ return [];
113
+ },
114
+ };
115
+
116
+ // SWAP: production resolves the buyer principal + AccountReference through
117
+ // your account directory or upstream OAuth `/me/adaccounts` equivalent.
118
+ function resolveSnapAccount(ref: AccountReference): SnapAccount | null {
119
+ if ('account_id' in ref) {
120
+ if (!ref.account_id) return null;
121
+ const sandbox = ref.account_id.startsWith('snap_sandbox_');
122
+ return {
123
+ id: ref.account_id,
124
+ name: sandbox ? 'Snap sandbox advertiser' : 'Snap advertiser',
125
+ status: 'active',
126
+ sandbox,
127
+ mode: sandbox ? 'sandbox' : 'live',
128
+ ctx_metadata: {
129
+ snap_ad_account_id: ref.account_id.replace(/^snap_/, ''),
130
+ bridge_session_id: `snap:${ref.account_id}`,
131
+ },
132
+ };
133
+ }
134
+
135
+ const domain = ref.brand.domain;
136
+ if (!domain) return null;
137
+ const sandbox = domain.endsWith('.sandbox');
138
+ return {
139
+ id: sandbox ? DEFAULT_SANDBOX_ACCOUNT_ID : `snap_${domain.replace(/[^a-z0-9]+/gi, '_').toLowerCase()}`,
140
+ name: `Snap advertiser for ${domain}`,
141
+ status: 'active',
142
+ sandbox,
143
+ mode: sandbox ? 'sandbox' : 'live',
144
+ brand: { domain },
145
+ ...(ref.operator !== undefined && { operator: ref.operator }),
146
+ ctx_metadata: {
147
+ snap_ad_account_id: sandbox ? 'sandbox_acme' : domain,
148
+ bridge_session_id: `snap:${sandbox ? DEFAULT_SANDBOX_ACCOUNT_ID : domain}`,
149
+ },
150
+ };
151
+ }
152
+
153
+ function requireResolvedAccount(account: SnapAccount | undefined): SnapAccount {
154
+ if (!account) {
155
+ throw new Error('TestControllerBridge requires resolveAccount; no resolved Snap account was available');
156
+ }
157
+ return account;
158
+ }
159
+
160
+ function readAccountId(input: Record<string, unknown>): string | undefined {
161
+ const account = input['account'];
162
+ if (!account || typeof account !== 'object') return undefined;
163
+ const accountId = (account as { account_id?: unknown }).account_id;
164
+ return typeof accountId === 'string' && accountId.length > 0 ? accountId : undefined;
165
+ }
166
+
167
+ function makeSnapBridge(sessionStore: InMemorySnapSessionStore): TestControllerBridge<SnapAccount> {
168
+ return bridgeFromSessionStore<SnapBridgeSession, SnapAccount>({
169
+ loadSession: (_input, ctx) => sessionStore.loadForAccount(requireResolvedAccount(ctx.account)),
170
+ selectSeededProducts: session => session.seededProducts,
171
+ selectSeededCreatives: session => session.seededCreatives,
172
+ selectSeededPropertyLists: session => session.seededPropertyLists,
173
+ productDefaults: {
174
+ name: 'Seeded Snap storyboard product',
175
+ description: 'Storyboard fixture merged by TestControllerBridge for wire conformance.',
176
+ publisher_properties: [{ publisher_domain: 'snap.com', selection_type: 'all' }],
177
+ channels: ['social'],
178
+ delivery_type: 'non_guaranteed',
179
+ format_ids: [{ agent_url: PUBLIC_AGENT_URL, id: 'snap-single-image' }],
180
+ pricing_options: [
181
+ {
182
+ pricing_option_id: 'snap-cpm-floor',
183
+ pricing_model: 'cpm',
184
+ currency: 'USD',
185
+ floor_price: 5,
186
+ },
187
+ ],
188
+ reporting_capabilities: {
189
+ available_reporting_frequencies: ['daily'],
190
+ expected_delay_minutes: 60,
191
+ timezone: 'UTC',
192
+ supports_webhooks: false,
193
+ available_metrics: ['impressions', 'clicks', 'spend'],
194
+ date_range_support: 'date_range',
195
+ },
196
+ },
197
+ });
198
+ }
199
+
200
+ export interface CreateProxySellerSnapServerOptions {
201
+ snapClient?: SnapClient;
202
+ sessionStore?: InMemorySnapSessionStore;
203
+ enableComplyTestController?: boolean;
204
+ validation?: {
205
+ requests?: ValidationMode;
206
+ responses?: ValidationMode;
207
+ };
208
+ }
209
+
210
+ export function createProxySellerSnapServer(options: CreateProxySellerSnapServerOptions = {}) {
211
+ const snapClient = options.snapClient ?? emptySnapClient;
212
+ const sessionStore = options.sessionStore ?? createInMemorySnapSessionStore();
213
+
214
+ const server = createAdcpServer<SnapAccount>({
215
+ name: 'proxy-seller-snap',
216
+ version: '1.0.0',
217
+ stateStore: new InMemoryStateStore(),
218
+ validation: options.validation ?? { requests: 'warn', responses: 'strict' },
219
+ resolveAccount: async ref => resolveSnapAccount(ref),
220
+ resolveSessionKey: ctx => ctx.account?.id ?? 'snap-anonymous',
221
+ mediaBuy: {
222
+ getProducts: async (_req, ctx) => ({
223
+ products: await snapClient.listProducts(requireResolvedAccount(ctx.account).ctx_metadata.snap_ad_account_id),
224
+ cache_scope: 'account',
225
+ }),
226
+ },
227
+ creative: {
228
+ listCreatives: async (_req, ctx) => {
229
+ const creatives = await snapClient.listCreatives(
230
+ requireResolvedAccount(ctx.account).ctx_metadata.snap_ad_account_id
231
+ );
232
+ return {
233
+ query_summary: { total_matching: creatives.length, returned: creatives.length },
234
+ pagination: { limit: 50, offset: 0, has_more: false },
235
+ creatives,
236
+ };
237
+ },
238
+ },
239
+ governance: {
240
+ listPropertyLists: async (_req, ctx) => {
241
+ const lists = await snapClient.listPropertyLists(
242
+ requireResolvedAccount(ctx.account).ctx_metadata.snap_ad_account_id
243
+ );
244
+ return {
245
+ lists,
246
+ pagination: { has_more: false },
247
+ };
248
+ },
249
+ getPropertyList: async (req, ctx) => {
250
+ const lists = await snapClient.listPropertyLists(
251
+ requireResolvedAccount(ctx.account).ctx_metadata.snap_ad_account_id
252
+ );
253
+ const list = lists.find(entry => entry.list_id === req.list_id);
254
+ if (!list) {
255
+ throw new AdcpError('REFERENCE_NOT_FOUND', {
256
+ message: 'Property list not found',
257
+ field: 'list_id',
258
+ });
259
+ }
260
+ return {
261
+ list,
262
+ identifiers: [],
263
+ pagination: { has_more: false },
264
+ };
265
+ },
266
+ },
267
+ testController: makeSnapBridge(sessionStore),
268
+ });
269
+
270
+ if (options.enableComplyTestController) {
271
+ createComplyController({
272
+ sandboxGate: input =>
273
+ process.env['ADCP_SANDBOX'] === '1' || readAccountId(input)?.startsWith('snap_sandbox_') === true,
274
+ inputSchema: {
275
+ account: z
276
+ .object({ account_id: z.string().optional(), sandbox: z.boolean().optional() })
277
+ .passthrough()
278
+ .optional(),
279
+ },
280
+ seed: {
281
+ product: ({ product_id, fixture }, ctx) => {
282
+ sessionStore.loadForControllerInput(ctx.input).seededProducts.set(product_id, fixture);
283
+ },
284
+ creative: ({ creative_id, fixture }, ctx) => {
285
+ const session = sessionStore.loadForControllerInput(ctx.input);
286
+ const withoutExisting = session.seededCreatives.filter(c => c.creative_id !== creative_id);
287
+ session.seededCreatives = [
288
+ ...withoutExisting,
289
+ {
290
+ creative_id,
291
+ name: typeof fixture['name'] === 'string' ? fixture['name'] : `Seeded Snap creative ${creative_id}`,
292
+ format_id: { agent_url: PUBLIC_AGENT_URL, id: 'snap-single-image' },
293
+ status: readCreativeStatus(fixture['status']),
294
+ created_date: new Date().toISOString(),
295
+ updated_date: new Date().toISOString(),
296
+ } as SeededCreative,
297
+ ];
298
+ },
299
+ },
300
+ }).register(server);
301
+ }
302
+
303
+ return server;
304
+ }
305
+
306
+ function readCreativeStatus(value: unknown): SeededCreative['status'] {
307
+ return value === 'approved' || value === 'pending_review' || value === 'rejected' || value === 'archived'
308
+ ? value
309
+ : 'pending_review';
310
+ }
311
+
312
+ if (require.main === module) {
313
+ serve(() => createProxySellerSnapServer({ enableComplyTestController: process.env['ADCP_SANDBOX'] === '1' }), {
314
+ port: PORT,
315
+ authenticate: verifyApiKey({
316
+ keys: { [ADCP_AUTH_TOKEN]: { principal: 'snap-proxy-harness' } },
317
+ }),
318
+ });
319
+
320
+ console.log(`proxy-seller-snap on http://127.0.0.1:${PORT}/mcp`);
321
+ }