@adcp/sdk 5.25.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/README.md +45 -7
  2. package/dist/lib/compliance-fixtures/index.d.ts +1 -1
  3. package/dist/lib/compliance-fixtures/index.js +1 -1
  4. package/dist/lib/conformance/runners.d.ts.map +1 -1
  5. package/dist/lib/conformance/runners.js +13 -1
  6. package/dist/lib/conformance/runners.js.map +1 -1
  7. package/dist/lib/core/AgentClient.d.ts.map +1 -1
  8. package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
  9. package/dist/lib/core/SingleAgentClient.js +15 -0
  10. package/dist/lib/core/SingleAgentClient.js.map +1 -1
  11. package/dist/lib/core/TaskExecutor.d.ts +7 -0
  12. package/dist/lib/core/TaskExecutor.d.ts.map +1 -1
  13. package/dist/lib/core/TaskExecutor.js +9 -2
  14. package/dist/lib/core/TaskExecutor.js.map +1 -1
  15. package/dist/lib/index.d.ts +1 -1
  16. package/dist/lib/index.d.ts.map +1 -1
  17. package/dist/lib/index.js +7 -8
  18. package/dist/lib/index.js.map +1 -1
  19. package/dist/lib/protocols/index.d.ts +3 -1
  20. package/dist/lib/protocols/index.d.ts.map +1 -1
  21. package/dist/lib/protocols/index.js +23 -14
  22. package/dist/lib/protocols/index.js.map +1 -1
  23. package/dist/lib/schemas/index.d.ts +1 -1
  24. package/dist/lib/schemas/index.js +1 -1
  25. package/dist/lib/server/create-adcp-server.d.ts +142 -11
  26. package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
  27. package/dist/lib/server/create-adcp-server.js +211 -2
  28. package/dist/lib/server/create-adcp-server.js.map +1 -1
  29. package/dist/lib/server/ctx-metadata/backends/memory.d.ts +27 -0
  30. package/dist/lib/server/ctx-metadata/backends/memory.d.ts.map +1 -0
  31. package/dist/lib/server/ctx-metadata/backends/memory.js +72 -0
  32. package/dist/lib/server/ctx-metadata/backends/memory.js.map +1 -0
  33. package/dist/lib/server/ctx-metadata/backends/pg.d.ts +62 -0
  34. package/dist/lib/server/ctx-metadata/backends/pg.d.ts.map +1 -0
  35. package/dist/lib/server/ctx-metadata/backends/pg.js +145 -0
  36. package/dist/lib/server/ctx-metadata/backends/pg.js.map +1 -0
  37. package/dist/lib/server/ctx-metadata/index.d.ts +15 -0
  38. package/dist/lib/server/ctx-metadata/index.d.ts.map +1 -0
  39. package/dist/lib/server/ctx-metadata/index.js +28 -0
  40. package/dist/lib/server/ctx-metadata/index.js.map +1 -0
  41. package/dist/lib/server/ctx-metadata/store.d.ts +177 -0
  42. package/dist/lib/server/ctx-metadata/store.d.ts.map +1 -0
  43. package/dist/lib/server/ctx-metadata/store.js +327 -0
  44. package/dist/lib/server/ctx-metadata/store.js.map +1 -0
  45. package/dist/lib/server/ctx-metadata/wire-shape.d.ts +55 -0
  46. package/dist/lib/server/ctx-metadata/wire-shape.d.ts.map +1 -0
  47. package/dist/lib/server/ctx-metadata/wire-shape.js +121 -0
  48. package/dist/lib/server/ctx-metadata/wire-shape.js.map +1 -0
  49. package/dist/lib/server/decisioning/account.d.ts +309 -0
  50. package/dist/lib/server/decisioning/account.d.ts.map +1 -0
  51. package/dist/lib/server/decisioning/account.js +102 -0
  52. package/dist/lib/server/decisioning/account.js.map +1 -0
  53. package/dist/lib/server/decisioning/admin-router.d.ts +75 -0
  54. package/dist/lib/server/decisioning/admin-router.d.ts.map +1 -0
  55. package/dist/lib/server/decisioning/admin-router.js +120 -0
  56. package/dist/lib/server/decisioning/admin-router.js.map +1 -0
  57. package/dist/lib/server/decisioning/assembly-helpers.d.ts +204 -0
  58. package/dist/lib/server/decisioning/assembly-helpers.d.ts.map +1 -0
  59. package/dist/lib/server/decisioning/assembly-helpers.js +173 -0
  60. package/dist/lib/server/decisioning/assembly-helpers.js.map +1 -0
  61. package/dist/lib/server/decisioning/async-outcome.d.ts +154 -0
  62. package/dist/lib/server/decisioning/async-outcome.d.ts.map +1 -0
  63. package/dist/lib/server/decisioning/async-outcome.js +239 -0
  64. package/dist/lib/server/decisioning/async-outcome.js.map +1 -0
  65. package/dist/lib/server/decisioning/capabilities.d.ts +251 -0
  66. package/dist/lib/server/decisioning/capabilities.d.ts.map +1 -0
  67. package/dist/lib/server/decisioning/capabilities.js +16 -0
  68. package/dist/lib/server/decisioning/capabilities.js.map +1 -0
  69. package/dist/lib/server/decisioning/context.d.ts +212 -0
  70. package/dist/lib/server/decisioning/context.d.ts.map +1 -0
  71. package/dist/lib/server/decisioning/context.js +26 -0
  72. package/dist/lib/server/decisioning/context.js.map +1 -0
  73. package/dist/lib/server/decisioning/errors-typed.d.ts +104 -0
  74. package/dist/lib/server/decisioning/errors-typed.d.ts.map +1 -0
  75. package/dist/lib/server/decisioning/errors-typed.js +304 -0
  76. package/dist/lib/server/decisioning/errors-typed.js.map +1 -0
  77. package/dist/lib/server/decisioning/helpers.d.ts +131 -0
  78. package/dist/lib/server/decisioning/helpers.d.ts.map +1 -0
  79. package/dist/lib/server/decisioning/helpers.js +134 -0
  80. package/dist/lib/server/decisioning/helpers.js.map +1 -0
  81. package/dist/lib/server/decisioning/index.d.ts +46 -0
  82. package/dist/lib/server/decisioning/index.d.ts.map +1 -0
  83. package/dist/lib/server/decisioning/index.js +120 -0
  84. package/dist/lib/server/decisioning/index.js.map +1 -0
  85. package/dist/lib/server/decisioning/list-helpers.d.ts +53 -0
  86. package/dist/lib/server/decisioning/list-helpers.d.ts.map +1 -0
  87. package/dist/lib/server/decisioning/list-helpers.js +96 -0
  88. package/dist/lib/server/decisioning/list-helpers.js.map +1 -0
  89. package/dist/lib/server/decisioning/manifest-helpers.d.ts +56 -0
  90. package/dist/lib/server/decisioning/manifest-helpers.d.ts.map +1 -0
  91. package/dist/lib/server/decisioning/manifest-helpers.js +78 -0
  92. package/dist/lib/server/decisioning/manifest-helpers.js.map +1 -0
  93. package/dist/lib/server/decisioning/pagination.d.ts +21 -0
  94. package/dist/lib/server/decisioning/pagination.d.ts.map +1 -0
  95. package/dist/lib/server/decisioning/pagination.js +12 -0
  96. package/dist/lib/server/decisioning/pagination.js.map +1 -0
  97. package/dist/lib/server/decisioning/platform.d.ts +188 -0
  98. package/dist/lib/server/decisioning/platform.d.ts.map +1 -0
  99. package/dist/lib/server/decisioning/platform.js +19 -0
  100. package/dist/lib/server/decisioning/platform.js.map +1 -0
  101. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +510 -0
  102. package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -0
  103. package/dist/lib/server/decisioning/runtime/from-platform.js +2196 -0
  104. package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -0
  105. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts +114 -0
  106. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts.map +1 -0
  107. package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +247 -0
  108. package/dist/lib/server/decisioning/runtime/postgres-task-registry.js.map +1 -0
  109. package/dist/lib/server/decisioning/runtime/protocol-for-tool.d.ts +32 -0
  110. package/dist/lib/server/decisioning/runtime/protocol-for-tool.d.ts.map +1 -0
  111. package/dist/lib/server/decisioning/runtime/protocol-for-tool.js +127 -0
  112. package/dist/lib/server/decisioning/runtime/protocol-for-tool.js.map +1 -0
  113. package/dist/lib/server/decisioning/runtime/task-registry.d.ts +105 -0
  114. package/dist/lib/server/decisioning/runtime/task-registry.d.ts.map +1 -0
  115. package/dist/lib/server/decisioning/runtime/task-registry.js +96 -0
  116. package/dist/lib/server/decisioning/runtime/task-registry.js.map +1 -0
  117. package/dist/lib/server/decisioning/runtime/to-context.d.ts +54 -0
  118. package/dist/lib/server/decisioning/runtime/to-context.d.ts.map +1 -0
  119. package/dist/lib/server/decisioning/runtime/to-context.js +166 -0
  120. package/dist/lib/server/decisioning/runtime/to-context.js.map +1 -0
  121. package/dist/lib/server/decisioning/runtime/validate-platform.d.ts +20 -0
  122. package/dist/lib/server/decisioning/runtime/validate-platform.d.ts.map +1 -0
  123. package/dist/lib/server/decisioning/runtime/validate-platform.js +93 -0
  124. package/dist/lib/server/decisioning/runtime/validate-platform.js.map +1 -0
  125. package/dist/lib/server/decisioning/specialisms/audiences.d.ts +72 -0
  126. package/dist/lib/server/decisioning/specialisms/audiences.d.ts.map +1 -0
  127. package/dist/lib/server/decisioning/specialisms/audiences.js +15 -0
  128. package/dist/lib/server/decisioning/specialisms/audiences.js.map +1 -0
  129. package/dist/lib/server/decisioning/specialisms/brand-rights.d.ts +92 -0
  130. package/dist/lib/server/decisioning/specialisms/brand-rights.d.ts.map +1 -0
  131. package/dist/lib/server/decisioning/specialisms/brand-rights.js +28 -0
  132. package/dist/lib/server/decisioning/specialisms/brand-rights.js.map +1 -0
  133. package/dist/lib/server/decisioning/specialisms/campaign-governance.d.ts +67 -0
  134. package/dist/lib/server/decisioning/specialisms/campaign-governance.d.ts.map +1 -0
  135. package/dist/lib/server/decisioning/specialisms/campaign-governance.js +31 -0
  136. package/dist/lib/server/decisioning/specialisms/campaign-governance.js.map +1 -0
  137. package/dist/lib/server/decisioning/specialisms/content-standards.d.ts +78 -0
  138. package/dist/lib/server/decisioning/specialisms/content-standards.d.ts.map +1 -0
  139. package/dist/lib/server/decisioning/specialisms/content-standards.js +35 -0
  140. package/dist/lib/server/decisioning/specialisms/content-standards.js.map +1 -0
  141. package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts +81 -0
  142. package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts.map +1 -0
  143. package/dist/lib/server/decisioning/specialisms/creative-ad-server.js +28 -0
  144. package/dist/lib/server/decisioning/specialisms/creative-ad-server.js.map +1 -0
  145. package/dist/lib/server/decisioning/specialisms/creative.d.ts +144 -0
  146. package/dist/lib/server/decisioning/specialisms/creative.d.ts.map +1 -0
  147. package/dist/lib/server/decisioning/specialisms/creative.js +19 -0
  148. package/dist/lib/server/decisioning/specialisms/creative.js.map +1 -0
  149. package/dist/lib/server/decisioning/specialisms/lists.d.ts +61 -0
  150. package/dist/lib/server/decisioning/specialisms/lists.d.ts.map +1 -0
  151. package/dist/lib/server/decisioning/specialisms/lists.js +30 -0
  152. package/dist/lib/server/decisioning/specialisms/lists.js.map +1 -0
  153. package/dist/lib/server/decisioning/specialisms/sales.d.ts +163 -0
  154. package/dist/lib/server/decisioning/specialisms/sales.d.ts.map +1 -0
  155. package/dist/lib/server/decisioning/specialisms/sales.js +64 -0
  156. package/dist/lib/server/decisioning/specialisms/sales.js.map +1 -0
  157. package/dist/lib/server/decisioning/specialisms/signals.d.ts +64 -0
  158. package/dist/lib/server/decisioning/specialisms/signals.d.ts.map +1 -0
  159. package/dist/lib/server/decisioning/specialisms/signals.js +28 -0
  160. package/dist/lib/server/decisioning/specialisms/signals.js.map +1 -0
  161. package/dist/lib/server/decisioning/start-time.d.ts +76 -0
  162. package/dist/lib/server/decisioning/start-time.d.ts.map +1 -0
  163. package/dist/lib/server/decisioning/start-time.js +81 -0
  164. package/dist/lib/server/decisioning/start-time.js.map +1 -0
  165. package/dist/lib/server/decisioning/status-changes.d.ts +165 -0
  166. package/dist/lib/server/decisioning/status-changes.d.ts.map +1 -0
  167. package/dist/lib/server/decisioning/status-changes.js +131 -0
  168. package/dist/lib/server/decisioning/status-changes.js.map +1 -0
  169. package/dist/lib/server/decisioning/status-mappers.d.ts +46 -0
  170. package/dist/lib/server/decisioning/status-mappers.d.ts.map +1 -0
  171. package/dist/lib/server/decisioning/status-mappers.js +46 -0
  172. package/dist/lib/server/decisioning/status-mappers.js.map +1 -0
  173. package/dist/lib/server/decisioning/tenant-registry.d.ts +289 -0
  174. package/dist/lib/server/decisioning/tenant-registry.d.ts.map +1 -0
  175. package/dist/lib/server/decisioning/tenant-registry.js +503 -0
  176. package/dist/lib/server/decisioning/tenant-registry.js.map +1 -0
  177. package/dist/lib/server/express-adapter.d.ts +1 -1
  178. package/dist/lib/server/express-adapter.js +1 -1
  179. package/dist/lib/server/governance.d.ts +1 -1
  180. package/dist/lib/server/governance.js +1 -1
  181. package/dist/lib/server/idempotency/store.d.ts +1 -1
  182. package/dist/lib/server/idempotency/store.js +1 -1
  183. package/dist/lib/server/index.d.ts +9 -2
  184. package/dist/lib/server/index.d.ts.map +1 -1
  185. package/dist/lib/server/index.js +79 -4
  186. package/dist/lib/server/index.js.map +1 -1
  187. package/dist/lib/server/legacy/v5/index.d.ts +38 -0
  188. package/dist/lib/server/legacy/v5/index.d.ts.map +1 -0
  189. package/dist/lib/server/legacy/v5/index.js +60 -0
  190. package/dist/lib/server/legacy/v5/index.js.map +1 -0
  191. package/dist/lib/server/normalize-errors.d.ts +88 -0
  192. package/dist/lib/server/normalize-errors.d.ts.map +1 -0
  193. package/dist/lib/server/normalize-errors.js +146 -0
  194. package/dist/lib/server/normalize-errors.js.map +1 -0
  195. package/dist/lib/server/pick-safe-details.d.ts +90 -0
  196. package/dist/lib/server/pick-safe-details.d.ts.map +1 -0
  197. package/dist/lib/server/pick-safe-details.js +148 -0
  198. package/dist/lib/server/pick-safe-details.js.map +1 -0
  199. package/dist/lib/server/postgres-state-store.d.ts +1 -1
  200. package/dist/lib/server/postgres-state-store.js +1 -1
  201. package/dist/lib/server/responses.d.ts +38 -0
  202. package/dist/lib/server/responses.d.ts.map +1 -1
  203. package/dist/lib/server/responses.js +38 -0
  204. package/dist/lib/server/responses.js.map +1 -1
  205. package/dist/lib/server/state-store.d.ts +1 -1
  206. package/dist/lib/server/state-store.js +1 -1
  207. package/dist/lib/server/test-controller.d.ts +10 -3
  208. package/dist/lib/server/test-controller.d.ts.map +1 -1
  209. package/dist/lib/server/test-controller.js +10 -3
  210. package/dist/lib/server/test-controller.js.map +1 -1
  211. package/dist/lib/testing/comply-controller.d.ts +47 -1
  212. package/dist/lib/testing/comply-controller.d.ts.map +1 -1
  213. package/dist/lib/testing/comply-controller.js +11 -4
  214. package/dist/lib/testing/comply-controller.js.map +1 -1
  215. package/dist/lib/testing/index.d.ts +1 -1
  216. package/dist/lib/testing/index.d.ts.map +1 -1
  217. package/dist/lib/testing/index.js.map +1 -1
  218. package/dist/lib/testing/personas/index.d.ts +143 -0
  219. package/dist/lib/testing/personas/index.d.ts.map +1 -0
  220. package/dist/lib/testing/personas/index.js +190 -0
  221. package/dist/lib/testing/personas/index.js.map +1 -0
  222. package/dist/lib/testing/storyboard/index.d.ts +1 -1
  223. package/dist/lib/testing/storyboard/index.d.ts.map +1 -1
  224. package/dist/lib/testing/storyboard/index.js +3 -2
  225. package/dist/lib/testing/storyboard/index.js.map +1 -1
  226. package/dist/lib/testing/storyboard/runner.d.ts +13 -0
  227. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  228. package/dist/lib/testing/storyboard/runner.js +179 -7
  229. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  230. package/dist/lib/types/adcp.d.ts.map +1 -1
  231. package/dist/lib/types/adcp.js +1 -0
  232. package/dist/lib/types/adcp.js.map +1 -1
  233. package/dist/lib/types/asset-instances.d.ts +1 -0
  234. package/dist/lib/types/asset-instances.d.ts.map +1 -1
  235. package/dist/lib/types/core.generated.d.ts +203 -98
  236. package/dist/lib/types/core.generated.d.ts.map +1 -1
  237. package/dist/lib/types/core.generated.js +1 -1
  238. package/dist/lib/types/index.d.ts +1 -0
  239. package/dist/lib/types/index.d.ts.map +1 -1
  240. package/dist/lib/types/index.js.map +1 -1
  241. package/dist/lib/types/schemas.generated.d.ts +599 -159
  242. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  243. package/dist/lib/types/schemas.generated.js +175 -94
  244. package/dist/lib/types/schemas.generated.js.map +1 -1
  245. package/dist/lib/types/tools.generated.d.ts +315 -46
  246. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  247. package/dist/lib/utils/capabilities.d.ts +1 -1
  248. package/dist/lib/utils/capabilities.d.ts.map +1 -1
  249. package/dist/lib/utils/capabilities.js +6 -0
  250. package/dist/lib/utils/capabilities.js.map +1 -1
  251. package/dist/lib/validation/schema-validator.d.ts +13 -0
  252. package/dist/lib/validation/schema-validator.d.ts.map +1 -1
  253. package/dist/lib/validation/schema-validator.js +240 -3
  254. package/dist/lib/validation/schema-validator.js.map +1 -1
  255. package/dist/lib/version.d.ts +3 -3
  256. package/dist/lib/version.d.ts.map +1 -1
  257. package/dist/lib/version.js +3 -3
  258. package/dist/lib/version.js.map +1 -1
  259. package/docs/guides/BUILD-AN-AGENT.md +30 -5
  260. package/docs/llms.txt +28 -17
  261. package/examples/README.md +3 -1
  262. package/examples/decisioning-platform-broadcast-tv.ts +300 -0
  263. package/examples/decisioning-platform-identity-graph.ts +214 -0
  264. package/examples/decisioning-platform-mock-seller.ts +332 -0
  265. package/examples/decisioning-platform-multi-tenant.ts +128 -0
  266. package/examples/decisioning-platform-programmatic.ts +254 -0
  267. package/examples/signals-agent.ts +1 -1
  268. package/package.json +13 -2
  269. package/skills/build-brand-rights-agent/SKILL.md +10 -3
  270. package/skills/build-creative-agent/SKILL.md +94 -64
  271. package/skills/build-decisioning-creative-template/SKILL.md +554 -0
  272. package/skills/build-decisioning-platform/SKILL.md +304 -0
  273. package/skills/build-decisioning-platform/advanced/BRAND-RIGHTS.md +25 -0
  274. package/skills/build-decisioning-platform/advanced/COMPLIANCE.md +23 -0
  275. package/skills/build-decisioning-platform/advanced/GOVERNANCE.md +24 -0
  276. package/skills/build-decisioning-platform/advanced/HITL.md +34 -0
  277. package/skills/build-decisioning-platform/advanced/IDEMPOTENCY.md +52 -0
  278. package/skills/build-decisioning-platform/advanced/MULTI-TENANT.md +47 -0
  279. package/skills/build-decisioning-platform/advanced/OAUTH.md +22 -0
  280. package/skills/build-decisioning-platform/advanced/REFERENCE.md +991 -0
  281. package/skills/build-decisioning-platform/advanced/SANDBOX.md +24 -0
  282. package/skills/build-decisioning-platform/advanced/STATE-MACHINE.md +52 -0
  283. package/skills/build-decisioning-signal-marketplace/SKILL.md +269 -0
  284. package/skills/build-generative-seller-agent/SKILL.md +89 -53
  285. package/skills/build-governance-agent/SKILL.md +76 -45
  286. package/skills/build-retail-media-agent/SKILL.md +87 -62
  287. package/skills/build-seller-agent/SKILL.md +384 -255
  288. package/skills/build-seller-agent/deployment.md +5 -3
  289. package/skills/build-seller-agent/specialisms/audience-sync.md +0 -2
  290. package/skills/build-seller-agent/specialisms/sales-broadcast-tv.md +0 -2
  291. package/skills/build-seller-agent/specialisms/sales-guaranteed.md +0 -2
  292. package/skills/build-seller-agent/specialisms/sales-non-guaranteed.md +0 -2
  293. package/skills/build-seller-agent/specialisms/sales-proposal-mode.md +0 -2
  294. package/skills/build-seller-agent/specialisms/sales-social.md +0 -2
  295. package/skills/build-seller-agent/specialisms/signed-requests.md +0 -2
  296. package/skills/build-si-agent/SKILL.md +40 -32
  297. package/skills/build-signals-agent/SKILL.md +139 -92
  298. package/skills/call-adcp-agent.previous/SKILL.md +5 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/server/ctx-metadata/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,iCAQiB;AAPf,+GAAA,sBAAsB,OAAA;AACtB,6GAAA,oBAAoB,OAAA;AACpB,4GAAA,mBAAmB,OAAA;AACnB,mHAAA,0BAA0B,OAAA;AAC1B,0GAAA,iBAAiB,OAAA;AACjB,gHAAA,uBAAuB,OAAA;AACvB,wGAAA,eAAe,OAAA;AAYjB,4CAA2D;AAAlD,gHAAA,sBAAsB,OAAA;AAG/B,oCAKuB;AAJrB,wGAAA,kBAAkB,OAAA;AAClB,6GAAA,uBAAuB,OAAA;AACvB,+GAAA,yBAAyB,OAAA;AACzB,4GAAA,sBAAsB,OAAA;AAIxB,2CAAgE;AAAvD,8GAAA,gBAAgB,OAAA;AAAE,4GAAA,cAAc,OAAA"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Ctx-metadata store for AdCP server handlers.
3
+ *
4
+ * Publishers attach platform-specific opaque blobs to any returned
5
+ * resource (product, media_buy, package, creative, audience, signal,
6
+ * rights_grant). The framework persists the blob keyed by
7
+ * `(account_id, kind, id)`, strips it from buyer-facing wire payloads,
8
+ * and threads it back into the publisher's request context on
9
+ * subsequent calls referencing the same resource ID.
10
+ *
11
+ * Use case: GAM ad_unit_ids per product, GAM order_id per media_buy,
12
+ * line_item_id per package — adapter-internal state the AdCP wire
13
+ * spec doesn't model. Avoids forcing publishers to re-derive on every
14
+ * call or maintain a side-cache the SDK could provide.
15
+ *
16
+ * Scope is `(account_id, kind, id)` — keys are tenant-isolated. No
17
+ * auto-eviction by design (a media buy lifetime can be months).
18
+ * Adopter-driven cleanup via `cleanupExpiredCtxMetadata(db)` for
19
+ * Postgres deployments that opt into row-level `expires_at`.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { createCtxMetadataStore, memoryCtxMetadataStore } from '@adcp/sdk/server';
24
+ *
25
+ * const store = createCtxMetadataStore({ backend: memoryCtxMetadataStore() });
26
+ *
27
+ * createAdcpServerFromPlatform({ platform, ctxMetadata: store });
28
+ * ```
29
+ *
30
+ * @public
31
+ */
32
+ /**
33
+ * Resource kinds the ctx-metadata store recognizes. Closed enum:
34
+ * adding a new kind is a coordinated change across the framework
35
+ * dispatch (which kinds get hydrated on which request shapes).
36
+ */
37
+ export type ResourceKind = 'account' | 'product' | 'media_buy' | 'package' | 'creative' | 'audience' | 'signal' | 'rights_grant' | 'property_list' | 'collection_list';
38
+ /**
39
+ * Default size cap on serialized blob, in bytes. Crossed → `CTX_METADATA_TOO_LARGE`.
40
+ *
41
+ * Memory backend without a cap is a single-node DoS vector; Postgres
42
+ * JSONB performance dies at scale before disk does. 16KB covers the
43
+ * common case (ad_unit_ids arrays, key-value targeting maps) with
44
+ * room to spare.
45
+ */
46
+ export declare const DEFAULT_MAX_VALUE_BYTES: number;
47
+ /**
48
+ * Maximum allowed TTL in seconds. Crossed → throws at `set()`.
49
+ *
50
+ * Lifetime of a media buy can be months, but unbounded retention
51
+ * compounds drift between SDK cache and publisher truth. 30 days is
52
+ * the soft ceiling; cleanup is adopter-driven beyond that.
53
+ */
54
+ export declare const MAX_TTL_SECONDS: number;
55
+ /**
56
+ * Symbol tag attached to retrieved blobs. Symbols don't survive
57
+ * `JSON.stringify`, so an accidental serialization in error envelopes
58
+ * / log lines / agent-card payloads silently elides the blob.
59
+ * Defense-in-depth against LLM-context leaks.
60
+ */
61
+ export declare const ADCP_INTERNAL_TAG: unique symbol;
62
+ export interface CtxMetadataEntry {
63
+ /** Opaque publisher-attached value. Untouched by the framework. */
64
+ value: unknown;
65
+ /**
66
+ * SDK-attached AdCP wire resource shape (e.g., the full `Product` /
67
+ * `MediaBuy` / `Creative` object minus `ctx_metadata`). Populated by
68
+ * the framework's auto-hydration path, not by adopter code.
69
+ *
70
+ * Used to reconstruct a hydrated resource on subsequent calls that
71
+ * reference the same id by string. Buyer sends `product_id: 'p1'`;
72
+ * SDK looks up the entry, builds `{ ...resource, ctx_metadata: value }`,
73
+ * attaches as `req.packages[i].product`.
74
+ *
75
+ * Adopter code never reads or writes this field — the framework owns
76
+ * it end-to-end.
77
+ */
78
+ resource?: unknown;
79
+ /** Optional unix epoch seconds expiry. Informational; no auto-eviction. */
80
+ expiresAt?: number;
81
+ }
82
+ /**
83
+ * Storage backend interface. Swap implementations for memory / Postgres / Redis.
84
+ *
85
+ * Keys are flattened to `${accountId}${kind}${id}` before
86
+ * reaching the backend. Validation runs before flattening — backends
87
+ * trust their inputs.
88
+ */
89
+ export interface CtxMetadataBackend {
90
+ get(scopedKey: string): Promise<CtxMetadataEntry | null>;
91
+ bulkGet(scopedKeys: readonly string[]): Promise<Map<string, CtxMetadataEntry>>;
92
+ put(scopedKey: string, entry: CtxMetadataEntry): Promise<void>;
93
+ delete(scopedKey: string): Promise<void>;
94
+ /** Optional startup probe. Implementations wrapping an external store should implement. */
95
+ probe?(): Promise<void>;
96
+ /** Optional resource-release hook. Called by `store.close()`. */
97
+ close?(): Promise<void>;
98
+ /** Optional test-harness flush. Used by `compliance.reset()` between storyboards. */
99
+ clearAll?(): Promise<void>;
100
+ }
101
+ export interface CtxMetadataStoreConfig {
102
+ /** Storage backend. Use `memoryCtxMetadataStore()` for dev, `pgCtxMetadataStore(pool)` for cluster. */
103
+ backend: CtxMetadataBackend;
104
+ /**
105
+ * Max serialized blob size in bytes. Defaults to 16384 (16KB).
106
+ * Crossed → `CTX_METADATA_TOO_LARGE` thrown at `set()`.
107
+ */
108
+ maxValueBytes?: number;
109
+ }
110
+ /**
111
+ * Reference to a stored entry. `bulkGet` accepts an array of these;
112
+ * the resulting Map is keyed by `${kind}:${id}` for caller convenience.
113
+ */
114
+ export interface CtxMetadataRef {
115
+ kind: ResourceKind;
116
+ id: string;
117
+ }
118
+ export interface CtxMetadataStore {
119
+ /**
120
+ * Look up a single entry. Returns `undefined` (not `null`) for misses
121
+ * so publishers can branch with `??` against their own DB.
122
+ *
123
+ * Returned values carry a non-enumerable `[ADCP_INTERNAL_TAG]: true`
124
+ * marker — JSON serialization elides it automatically (defense
125
+ * against accidental leak via error envelopes and log lines).
126
+ */
127
+ get(accountId: string, kind: ResourceKind, id: string): Promise<unknown | undefined>;
128
+ /**
129
+ * Bulk lookup. Returns a Map keyed by `${kind}:${id}` so callers
130
+ * with mixed-kind refs (e.g., `create_media_buy` carrying products
131
+ * + an audience ref) can index without remembering what they asked for.
132
+ * Misses are absent from the Map (no `undefined` entries).
133
+ */
134
+ bulkGet(accountId: string, refs: readonly CtxMetadataRef[]): Promise<ReadonlyMap<string, unknown>>;
135
+ /**
136
+ * Store a blob. Throws `CTX_METADATA_TOO_LARGE` if `JSON.stringify(value).length`
137
+ * exceeds the configured cap. Throws `INVALID_ARGUMENT` for null/undefined/empty
138
+ * `accountId` or out-of-shape `id`.
139
+ *
140
+ * `ttlSeconds` is optional and capped at 30 days. No auto-eviction.
141
+ */
142
+ set(accountId: string, kind: ResourceKind, id: string, value: unknown, ttlSeconds?: number): Promise<void>;
143
+ /** Delete a single entry. Tenant-scoped via `accountId`. */
144
+ delete(accountId: string, kind: ResourceKind, id: string): Promise<void>;
145
+ /** Probe the backend for boot-time readiness. */
146
+ probe(): Promise<void>;
147
+ /** Release backend resources (close pools, clear timers). */
148
+ close(): Promise<void>;
149
+ /** Test-harness reset. Throws if backend doesn't support it (no `force` opt — production safety). */
150
+ clearAll(): Promise<void>;
151
+ }
152
+ /**
153
+ * Validation error thrown for bad input shape. Distinct from
154
+ * `CTX_METADATA_TOO_LARGE` (size violation) so callers can branch.
155
+ */
156
+ export declare class CtxMetadataValidationError extends Error {
157
+ readonly code: 'INVALID_ARGUMENT' | 'CTX_METADATA_TOO_LARGE';
158
+ constructor(code: 'INVALID_ARGUMENT' | 'CTX_METADATA_TOO_LARGE', message: string);
159
+ }
160
+ /**
161
+ * Compose the flattened storage key. Internal — backends trust this format.
162
+ */
163
+ export declare function scopeCtxMetadataKey(accountId: string, kind: ResourceKind, id: string): string;
164
+ /**
165
+ * Compose the bulkGet result key. External — callers index Map entries by this.
166
+ */
167
+ export declare function ctxMetadataResultKey(kind: ResourceKind, id: string): string;
168
+ /**
169
+ * Build a CtxMetadataStore wrapping a backend.
170
+ *
171
+ * Memory backend is fine for single-process dev. Cluster deployments
172
+ * MUST use `pgCtxMetadataStore` — silent ctx_metadata loss after a
173
+ * rolling restart produces "package not found" errors that look like
174
+ * publisher bugs and run for weeks.
175
+ */
176
+ export declare function createCtxMetadataStore(config: CtxMetadataStoreConfig): CtxMetadataStore;
177
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/ctx-metadata/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,327 @@
1
+ "use strict";
2
+ /**
3
+ * Ctx-metadata store for AdCP server handlers.
4
+ *
5
+ * Publishers attach platform-specific opaque blobs to any returned
6
+ * resource (product, media_buy, package, creative, audience, signal,
7
+ * rights_grant). The framework persists the blob keyed by
8
+ * `(account_id, kind, id)`, strips it from buyer-facing wire payloads,
9
+ * and threads it back into the publisher's request context on
10
+ * subsequent calls referencing the same resource ID.
11
+ *
12
+ * Use case: GAM ad_unit_ids per product, GAM order_id per media_buy,
13
+ * line_item_id per package — adapter-internal state the AdCP wire
14
+ * spec doesn't model. Avoids forcing publishers to re-derive on every
15
+ * call or maintain a side-cache the SDK could provide.
16
+ *
17
+ * Scope is `(account_id, kind, id)` — keys are tenant-isolated. No
18
+ * auto-eviction by design (a media buy lifetime can be months).
19
+ * Adopter-driven cleanup via `cleanupExpiredCtxMetadata(db)` for
20
+ * Postgres deployments that opt into row-level `expires_at`.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { createCtxMetadataStore, memoryCtxMetadataStore } from '@adcp/sdk/server';
25
+ *
26
+ * const store = createCtxMetadataStore({ backend: memoryCtxMetadataStore() });
27
+ *
28
+ * createAdcpServerFromPlatform({ platform, ctxMetadata: store });
29
+ * ```
30
+ *
31
+ * @public
32
+ */
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.CtxMetadataValidationError = exports.ADCP_INTERNAL_TAG = exports.MAX_TTL_SECONDS = exports.DEFAULT_MAX_VALUE_BYTES = void 0;
35
+ exports.scopeCtxMetadataKey = scopeCtxMetadataKey;
36
+ exports.ctxMetadataResultKey = ctxMetadataResultKey;
37
+ exports.createCtxMetadataStore = createCtxMetadataStore;
38
+ const ALL_RESOURCE_KINDS = [
39
+ 'account',
40
+ 'product',
41
+ 'media_buy',
42
+ 'package',
43
+ 'creative',
44
+ 'audience',
45
+ 'signal',
46
+ 'rights_grant',
47
+ 'property_list',
48
+ 'collection_list',
49
+ ];
50
+ /**
51
+ * Default size cap on serialized blob, in bytes. Crossed → `CTX_METADATA_TOO_LARGE`.
52
+ *
53
+ * Memory backend without a cap is a single-node DoS vector; Postgres
54
+ * JSONB performance dies at scale before disk does. 16KB covers the
55
+ * common case (ad_unit_ids arrays, key-value targeting maps) with
56
+ * room to spare.
57
+ */
58
+ exports.DEFAULT_MAX_VALUE_BYTES = 16 * 1024;
59
+ /**
60
+ * Maximum allowed TTL in seconds. Crossed → throws at `set()`.
61
+ *
62
+ * Lifetime of a media buy can be months, but unbounded retention
63
+ * compounds drift between SDK cache and publisher truth. 30 days is
64
+ * the soft ceiling; cleanup is adopter-driven beyond that.
65
+ */
66
+ exports.MAX_TTL_SECONDS = 30 * 24 * 60 * 60;
67
+ /**
68
+ * Account ID and resource ID shape allowlist. Excludes the U+001F
69
+ * separator used in the flattened storage key, NUL bytes that
70
+ * Postgres TEXT rejects, and anything else that could confuse the
71
+ * key parser.
72
+ */
73
+ const VALID_KEY_SEGMENT = /^[A-Za-z0-9_.:\-]{1,255}$/;
74
+ /**
75
+ * Symbol tag attached to retrieved blobs. Symbols don't survive
76
+ * `JSON.stringify`, so an accidental serialization in error envelopes
77
+ * / log lines / agent-card payloads silently elides the blob.
78
+ * Defense-in-depth against LLM-context leaks.
79
+ */
80
+ exports.ADCP_INTERNAL_TAG = Symbol.for('adcp.ctx_metadata.internal');
81
+ /**
82
+ * Validation error thrown for bad input shape. Distinct from
83
+ * `CTX_METADATA_TOO_LARGE` (size violation) so callers can branch.
84
+ */
85
+ class CtxMetadataValidationError extends Error {
86
+ code;
87
+ constructor(code, message) {
88
+ super(message);
89
+ this.code = code;
90
+ this.name = 'CtxMetadataValidationError';
91
+ }
92
+ }
93
+ exports.CtxMetadataValidationError = CtxMetadataValidationError;
94
+ /**
95
+ * Compose the flattened storage key. Internal — backends trust this format.
96
+ */
97
+ function scopeCtxMetadataKey(accountId, kind, id) {
98
+ return `${accountId}${kind}${id}`;
99
+ }
100
+ /**
101
+ * Compose the bulkGet result key. External — callers index Map entries by this.
102
+ */
103
+ function ctxMetadataResultKey(kind, id) {
104
+ return `${kind}:${id}`;
105
+ }
106
+ function validateAccountId(accountId) {
107
+ if (accountId == null || accountId === '') {
108
+ throw new CtxMetadataValidationError('INVALID_ARGUMENT', 'ctx_metadata requires an account scope. No-account tools (provide_performance_feedback, ' +
109
+ 'list_creative_formats) cannot use ctx_metadata.');
110
+ }
111
+ if (!VALID_KEY_SEGMENT.test(accountId)) {
112
+ throw new CtxMetadataValidationError('INVALID_ARGUMENT', `Invalid accountId shape: must match ${VALID_KEY_SEGMENT}`);
113
+ }
114
+ }
115
+ function validateResourceId(id) {
116
+ if (id == null || id === '') {
117
+ throw new CtxMetadataValidationError('INVALID_ARGUMENT', 'ctx_metadata resource id must be non-empty');
118
+ }
119
+ if (!VALID_KEY_SEGMENT.test(id)) {
120
+ throw new CtxMetadataValidationError('INVALID_ARGUMENT', `Invalid resource id shape: must match ${VALID_KEY_SEGMENT}`);
121
+ }
122
+ }
123
+ function validateResourceKind(kind) {
124
+ if (!ALL_RESOURCE_KINDS.includes(kind)) {
125
+ throw new CtxMetadataValidationError('INVALID_ARGUMENT', `Unknown ctx_metadata resource kind: ${kind}`);
126
+ }
127
+ }
128
+ function tagInternal(value) {
129
+ if (value == null || typeof value !== 'object')
130
+ return value;
131
+ Object.defineProperty(value, exports.ADCP_INTERNAL_TAG, {
132
+ value: true,
133
+ enumerable: false,
134
+ writable: false,
135
+ configurable: false,
136
+ });
137
+ return value;
138
+ }
139
+ /**
140
+ * Build a CtxMetadataStore wrapping a backend.
141
+ *
142
+ * Memory backend is fine for single-process dev. Cluster deployments
143
+ * MUST use `pgCtxMetadataStore` — silent ctx_metadata loss after a
144
+ * rolling restart produces "package not found" errors that look like
145
+ * publisher bugs and run for weeks.
146
+ */
147
+ function createCtxMetadataStore(config) {
148
+ const backend = config.backend;
149
+ const maxValueBytes = config.maxValueBytes ?? exports.DEFAULT_MAX_VALUE_BYTES;
150
+ return {
151
+ async get(accountId, kind, id) {
152
+ validateAccountId(accountId);
153
+ validateResourceKind(kind);
154
+ validateResourceId(id);
155
+ const entry = await backend.get(scopeCtxMetadataKey(accountId, kind, id));
156
+ if (!entry)
157
+ return undefined;
158
+ if (entry.expiresAt != null && entry.expiresAt < Math.floor(Date.now() / 1000)) {
159
+ return undefined;
160
+ }
161
+ return tagInternal(entry.value);
162
+ },
163
+ async bulkGet(accountId, refs) {
164
+ validateAccountId(accountId);
165
+ if (refs.length === 0)
166
+ return new Map();
167
+ const scopedKeys = [];
168
+ const scopedToResultKey = new Map();
169
+ for (const ref of refs) {
170
+ validateResourceKind(ref.kind);
171
+ validateResourceId(ref.id);
172
+ const scoped = scopeCtxMetadataKey(accountId, ref.kind, ref.id);
173
+ scopedKeys.push(scoped);
174
+ scopedToResultKey.set(scoped, ctxMetadataResultKey(ref.kind, ref.id));
175
+ }
176
+ const entries = await backend.bulkGet(scopedKeys);
177
+ const result = new Map();
178
+ const nowSeconds = Math.floor(Date.now() / 1000);
179
+ for (const [scopedKey, entry] of entries) {
180
+ if (entry.expiresAt != null && entry.expiresAt < nowSeconds)
181
+ continue;
182
+ const resultKey = scopedToResultKey.get(scopedKey);
183
+ if (resultKey != null)
184
+ result.set(resultKey, tagInternal(entry.value));
185
+ }
186
+ return result;
187
+ },
188
+ async set(accountId, kind, id, value, ttlSeconds) {
189
+ validateAccountId(accountId);
190
+ validateResourceKind(kind);
191
+ validateResourceId(id);
192
+ if (ttlSeconds != null) {
193
+ if (!Number.isFinite(ttlSeconds) || ttlSeconds <= 0) {
194
+ throw new CtxMetadataValidationError('INVALID_ARGUMENT', 'ttlSeconds must be a positive finite number');
195
+ }
196
+ if (ttlSeconds > exports.MAX_TTL_SECONDS) {
197
+ throw new CtxMetadataValidationError('INVALID_ARGUMENT', `ttlSeconds exceeds the 30-day maximum (${exports.MAX_TTL_SECONDS}s)`);
198
+ }
199
+ }
200
+ const serialized = JSON.stringify(value);
201
+ if (serialized == null) {
202
+ throw new CtxMetadataValidationError('INVALID_ARGUMENT', 'ctx_metadata value must be JSON-serializable (got undefined / function / symbol)');
203
+ }
204
+ const byteLen = Buffer.byteLength(serialized, 'utf8');
205
+ if (byteLen > maxValueBytes) {
206
+ throw new CtxMetadataValidationError('CTX_METADATA_TOO_LARGE', `ctx_metadata blob is ${byteLen} bytes, exceeds the configured cap of ${maxValueBytes} bytes ` +
207
+ `for ${kind}:${id}. Offload large payloads to your own storage and reference by ID.`);
208
+ }
209
+ const expiresAt = ttlSeconds != null ? Math.floor(Date.now() / 1000) + ttlSeconds : undefined;
210
+ // Preserve any prior `resource` from the framework-managed entry —
211
+ // adopter `set()` only mutates `value`. The dispatch seam writes
212
+ // resource via `setEntry`.
213
+ const prior = await backend.get(scopeCtxMetadataKey(accountId, kind, id));
214
+ const next = {
215
+ value,
216
+ ...(prior?.resource !== undefined && { resource: prior.resource }),
217
+ ...(expiresAt !== undefined
218
+ ? { expiresAt }
219
+ : prior?.expiresAt !== undefined
220
+ ? { expiresAt: prior.expiresAt }
221
+ : {}),
222
+ };
223
+ await backend.put(scopeCtxMetadataKey(accountId, kind, id), next);
224
+ },
225
+ async setEntry(accountId, kind, id, entry) {
226
+ validateAccountId(accountId);
227
+ validateResourceKind(kind);
228
+ validateResourceId(id);
229
+ // Cap applied to the COMBINED serialization (value + resource) since
230
+ // both round-trip together. Use the same upstream message so adopters
231
+ // see the same diagnostic surface.
232
+ const serialized = JSON.stringify({ value: entry.value, resource: entry.resource });
233
+ const byteLen = Buffer.byteLength(serialized, 'utf8');
234
+ if (byteLen > maxValueBytes) {
235
+ throw new CtxMetadataValidationError('CTX_METADATA_TOO_LARGE', `ctx_metadata combined blob is ${byteLen} bytes, exceeds the configured cap of ${maxValueBytes} bytes ` +
236
+ `for ${kind}:${id}. Offload large payloads to your own storage and reference by ID.`);
237
+ }
238
+ await backend.put(scopeCtxMetadataKey(accountId, kind, id), entry);
239
+ },
240
+ async setResource(accountId, kind, id, resource, publisherCtxMetadata) {
241
+ validateAccountId(accountId);
242
+ validateResourceKind(kind);
243
+ validateResourceId(id);
244
+ const scopedKey = scopeCtxMetadataKey(accountId, kind, id);
245
+ const prior = await backend.get(scopedKey);
246
+ // Resolve the value to persist:
247
+ // - publisher returned ctx_metadata on the wire shape → use it (overrides prior)
248
+ // - publisher omitted ctx_metadata → preserve prior value (don't clobber)
249
+ // - no prior, no publisher value → store null
250
+ const nextValue = publisherCtxMetadata !== undefined && publisherCtxMetadata !== null
251
+ ? publisherCtxMetadata
252
+ : (prior?.value ?? null);
253
+ const nextEntry = {
254
+ value: nextValue,
255
+ resource,
256
+ ...(prior?.expiresAt !== undefined && { expiresAt: prior.expiresAt }),
257
+ };
258
+ // Apply the same size cap used by setEntry.
259
+ const serialized = JSON.stringify({ value: nextEntry.value, resource: nextEntry.resource });
260
+ const byteLen = Buffer.byteLength(serialized, 'utf8');
261
+ if (byteLen > maxValueBytes) {
262
+ throw new CtxMetadataValidationError('CTX_METADATA_TOO_LARGE', `ctx_metadata combined blob is ${byteLen} bytes, exceeds the configured cap of ${maxValueBytes} bytes ` +
263
+ `for ${kind}:${id}. Offload large payloads to your own storage and reference by ID.`);
264
+ }
265
+ await backend.put(scopedKey, nextEntry);
266
+ },
267
+ async getEntry(accountId, kind, id) {
268
+ validateAccountId(accountId);
269
+ validateResourceKind(kind);
270
+ validateResourceId(id);
271
+ const entry = await backend.get(scopeCtxMetadataKey(accountId, kind, id));
272
+ if (!entry)
273
+ return undefined;
274
+ if (entry.expiresAt != null && entry.expiresAt < Math.floor(Date.now() / 1000)) {
275
+ return undefined;
276
+ }
277
+ return entry;
278
+ },
279
+ async bulkGetEntries(accountId, refs) {
280
+ validateAccountId(accountId);
281
+ if (refs.length === 0)
282
+ return new Map();
283
+ const scopedKeys = [];
284
+ const scopedToResultKey = new Map();
285
+ for (const ref of refs) {
286
+ validateResourceKind(ref.kind);
287
+ validateResourceId(ref.id);
288
+ const scoped = scopeCtxMetadataKey(accountId, ref.kind, ref.id);
289
+ scopedKeys.push(scoped);
290
+ scopedToResultKey.set(scoped, ctxMetadataResultKey(ref.kind, ref.id));
291
+ }
292
+ const entries = await backend.bulkGet(scopedKeys);
293
+ const result = new Map();
294
+ const nowSeconds = Math.floor(Date.now() / 1000);
295
+ for (const [scopedKey, entry] of entries) {
296
+ if (entry.expiresAt != null && entry.expiresAt < nowSeconds)
297
+ continue;
298
+ const resultKey = scopedToResultKey.get(scopedKey);
299
+ if (resultKey != null)
300
+ result.set(resultKey, entry);
301
+ }
302
+ return result;
303
+ },
304
+ async delete(accountId, kind, id) {
305
+ validateAccountId(accountId);
306
+ validateResourceKind(kind);
307
+ validateResourceId(id);
308
+ await backend.delete(scopeCtxMetadataKey(accountId, kind, id));
309
+ },
310
+ async probe() {
311
+ if (backend.probe)
312
+ await backend.probe();
313
+ },
314
+ async close() {
315
+ if (backend.close)
316
+ await backend.close();
317
+ },
318
+ async clearAll() {
319
+ if (!backend.clearAll) {
320
+ throw new Error('ctx_metadata backend does not support clearAll(). ' +
321
+ 'Production backends (e.g., shared Postgres) should refuse this; use memory backend for tests.');
322
+ }
323
+ await backend.clearAll();
324
+ },
325
+ };
326
+ }
327
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../src/lib/server/ctx-metadata/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Compile-time + runtime defense against `ctx_metadata` leaking into
3
+ * buyer-facing wire payloads.
4
+ *
5
+ * - **Compile-time:** `WireShape<T>` strips `ctx_metadata` from a type
6
+ * tree, so the framework's response builder return types refuse a
7
+ * payload that carries it.
8
+ * - **Runtime:** `stripCtxMetadata(value)` shape-aware shallow walk
9
+ * over known carrier locations (response root + `packages[]` +
10
+ * `creatives[]` + `audiences[]` + `signals[]` + `media_buys[]` +
11
+ * `products[]`). Catches custom-handler escape hatches and HITL
12
+ * task return values that re-introduce the field at runtime.
13
+ *
14
+ * Single chokepoint at the dispatcher seam. Strip runs *before* the
15
+ * idempotency cache write so cached replays don't leak.
16
+ *
17
+ * @public
18
+ */
19
+ /**
20
+ * Compile-time strip: recursively remove `ctx_metadata` from a type
21
+ * tree. Used as the framework's response-boundary type so a publisher
22
+ * payload that carries the field fails type-checking before it
23
+ * reaches the wire.
24
+ *
25
+ * Strips `ctx_metadata` at top level, inside arrays, and inside
26
+ * objects nested under `packages` / `creatives` / `audiences` /
27
+ * `signals` / `media_buys` / `products` — the carrier shapes the
28
+ * AdCP 3.0 wire spec defines. Other shapes pass through unchanged
29
+ * (the runtime walk is deliberately not recursive everywhere — see
30
+ * the docstring).
31
+ */
32
+ export type WireShape<T> = T extends ReadonlyArray<infer U> ? ReadonlyArray<WireShape<U>> : T extends object ? {
33
+ [K in keyof T as K extends 'ctx_metadata' ? never : K]: WireShape<T[K]>;
34
+ } : T;
35
+ /**
36
+ * Runtime strip. Walks known carrier shapes in the response and
37
+ * deletes `ctx_metadata` keys. Returns the input value (mutates in
38
+ * place — the dispatcher constructs a fresh response per call, so
39
+ * mutation is safe).
40
+ *
41
+ * **Why shape-aware shallow walk, not full recursion.** Full
42
+ * recursion is O(response size) and risks stripping a field a
43
+ * future spec adds with the same name elsewhere (e.g., a diagnostic
44
+ * envelope's `ctx_metadata`). Shape-aware walks the carrier
45
+ * locations defined by AdCP 3.0 — adding a new carrier requires
46
+ * updating this list, which is the right kind of friction.
47
+ */
48
+ export declare function stripCtxMetadata<T>(value: T): WireShape<T>;
49
+ /**
50
+ * Detect whether a payload contains `ctx_metadata` at any walked
51
+ * carrier location. Used by the test suite to assert wire payloads
52
+ * are clean — production code paths just call `stripCtxMetadata`.
53
+ */
54
+ export declare function hasCtxMetadata(value: unknown): boolean;
55
+ //# sourceMappingURL=wire-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-shape.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/ctx-metadata/wire-shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IACrB,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,CAAC,GAC5B,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAC3B,CAAC,SAAS,MAAM,GACd;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,cAAc,GAAG,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAC3E,CAAC,CAAC;AAEV;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAI1D;AA+CD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGtD"}