@adcp/sdk 12.0.0 → 12.0.2

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 (959) hide show
  1. package/dist/lib/adapters/content-standards-adapter.mjs +0 -6
  2. package/dist/lib/adapters/content-standards-adapter.mjs.map +1 -1
  3. package/dist/lib/adapters/derived-account-store.mjs +0 -6
  4. package/dist/lib/adapters/derived-account-store.mjs.map +1 -1
  5. package/dist/lib/adapters/governance-adapter.mjs +0 -6
  6. package/dist/lib/adapters/governance-adapter.mjs.map +1 -1
  7. package/dist/lib/adapters/implicit-account-store.mjs +0 -6
  8. package/dist/lib/adapters/implicit-account-store.mjs.map +1 -1
  9. package/dist/lib/adapters/index.mjs +0 -6
  10. package/dist/lib/adapters/index.mjs.map +1 -1
  11. package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs +0 -6
  12. package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs.map +1 -1
  13. package/dist/lib/adapters/legacy/v2-5/get_products.mjs +0 -6
  14. package/dist/lib/adapters/legacy/v2-5/get_products.mjs.map +1 -1
  15. package/dist/lib/adapters/legacy/v2-5/index.mjs +0 -6
  16. package/dist/lib/adapters/legacy/v2-5/index.mjs.map +1 -1
  17. package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs +0 -6
  18. package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs.map +1 -1
  19. package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs +0 -6
  20. package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs.map +1 -1
  21. package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs +0 -6
  22. package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs.map +1 -1
  23. package/dist/lib/adapters/legacy/v2-5/types.mjs +0 -6
  24. package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs +0 -6
  25. package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs.map +1 -1
  26. package/dist/lib/adapters/oauth-passthrough-resolver.mjs +0 -6
  27. package/dist/lib/adapters/oauth-passthrough-resolver.mjs.map +1 -1
  28. package/dist/lib/adapters/property-list-adapter.mjs +0 -6
  29. package/dist/lib/adapters/property-list-adapter.mjs.map +1 -1
  30. package/dist/lib/adapters/roster-account-store.mjs +0 -6
  31. package/dist/lib/adapters/roster-account-store.mjs.map +1 -1
  32. package/dist/lib/adapters/si-session-manager.mjs +0 -6
  33. package/dist/lib/adapters/si-session-manager.mjs.map +1 -1
  34. package/dist/lib/adapters/version/3.0/brand-fields.mjs +0 -6
  35. package/dist/lib/adapters/version/3.0/brand-fields.mjs.map +1 -1
  36. package/dist/lib/adapters/version/3.0/get-products.mjs +0 -6
  37. package/dist/lib/adapters/version/3.0/get-products.mjs.map +1 -1
  38. package/dist/lib/adapters/version/3.0/index.mjs +0 -6
  39. package/dist/lib/adapters/version/3.0/index.mjs.map +1 -1
  40. package/dist/lib/adapters/version/3.0/sync-accounts.mjs +0 -6
  41. package/dist/lib/adapters/version/3.0/sync-accounts.mjs.map +1 -1
  42. package/dist/lib/adapters/version/index.mjs +0 -6
  43. package/dist/lib/adapters/version/index.mjs.map +1 -1
  44. package/dist/lib/adapters/version/types.mjs +0 -6
  45. package/dist/lib/advanced.mjs +0 -6
  46. package/dist/lib/advanced.mjs.map +1 -1
  47. package/dist/lib/agents/index.generated.mjs +0 -6
  48. package/dist/lib/agents/index.generated.mjs.map +1 -1
  49. package/dist/lib/auth/index.mjs +0 -6
  50. package/dist/lib/auth/index.mjs.map +1 -1
  51. package/dist/lib/auth/oauth/CLIFlowHandler.mjs +0 -6
  52. package/dist/lib/auth/oauth/CLIFlowHandler.mjs.map +1 -1
  53. package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs +0 -6
  54. package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs.map +1 -1
  55. package/dist/lib/auth/oauth/MCPOAuthProvider.mjs +0 -6
  56. package/dist/lib/auth/oauth/MCPOAuthProvider.mjs.map +1 -1
  57. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs +0 -6
  58. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs.map +1 -1
  59. package/dist/lib/auth/oauth/authorization-required.mjs +0 -6
  60. package/dist/lib/auth/oauth/authorization-required.mjs.map +1 -1
  61. package/dist/lib/auth/oauth/diagnose.mjs +0 -6
  62. package/dist/lib/auth/oauth/diagnose.mjs.map +1 -1
  63. package/dist/lib/auth/oauth/diagnostics.mjs +0 -6
  64. package/dist/lib/auth/oauth/diagnostics.mjs.map +1 -1
  65. package/dist/lib/auth/oauth/discovery.mjs +0 -6
  66. package/dist/lib/auth/oauth/discovery.mjs.map +1 -1
  67. package/dist/lib/auth/oauth/file-storage.mjs +0 -6
  68. package/dist/lib/auth/oauth/file-storage.mjs.map +1 -1
  69. package/dist/lib/auth/oauth/index.mjs +0 -6
  70. package/dist/lib/auth/oauth/index.mjs.map +1 -1
  71. package/dist/lib/auth/oauth/secret-resolver.mjs +0 -6
  72. package/dist/lib/auth/oauth/secret-resolver.mjs.map +1 -1
  73. package/dist/lib/auth/oauth/storage-registry.mjs +0 -6
  74. package/dist/lib/auth/oauth/storage-registry.mjs.map +1 -1
  75. package/dist/lib/auth/oauth/types.mjs +0 -6
  76. package/dist/lib/auth/oauth/types.mjs.map +1 -1
  77. package/dist/lib/auth/oauth/web-flow.mjs +0 -6
  78. package/dist/lib/auth/oauth/web-flow.mjs.map +1 -1
  79. package/dist/lib/brand/index.mjs +0 -6
  80. package/dist/lib/brand/index.mjs.map +1 -1
  81. package/dist/lib/canonical-references/index.mjs +6 -7
  82. package/dist/lib/canonical-references/index.mjs.map +1 -1
  83. package/dist/lib/client/index.mjs +0 -6
  84. package/dist/lib/client/index.mjs.map +1 -1
  85. package/dist/lib/compliance/index.mjs +0 -6
  86. package/dist/lib/compliance/index.mjs.map +1 -1
  87. package/dist/lib/compliance-fixtures/index.mjs +0 -6
  88. package/dist/lib/compliance-fixtures/index.mjs.map +1 -1
  89. package/dist/lib/compliance-fixtures/test-authorization-server.mjs +0 -6
  90. package/dist/lib/compliance-fixtures/test-authorization-server.mjs.map +1 -1
  91. package/dist/lib/conformance/index.mjs +0 -6
  92. package/dist/lib/conformance/index.mjs.map +1 -1
  93. package/dist/lib/conformance/invariants/uniformError.mjs +0 -6
  94. package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
  95. package/dist/lib/conformance/invariants/uniformErrorComparator.mjs +0 -6
  96. package/dist/lib/conformance/invariants/uniformErrorComparator.mjs.map +1 -1
  97. package/dist/lib/conformance/oracle.mjs +0 -6
  98. package/dist/lib/conformance/oracle.mjs.map +1 -1
  99. package/dist/lib/conformance/runConformance.mjs +0 -6
  100. package/dist/lib/conformance/runConformance.mjs.map +1 -1
  101. package/dist/lib/conformance/runners.mjs +0 -6
  102. package/dist/lib/conformance/runners.mjs.map +1 -1
  103. package/dist/lib/conformance/schemaArbitrary.mjs +0 -6
  104. package/dist/lib/conformance/schemaArbitrary.mjs.map +1 -1
  105. package/dist/lib/conformance/schemaLoader.mjs +5 -6
  106. package/dist/lib/conformance/schemaLoader.mjs.map +1 -1
  107. package/dist/lib/conformance/seeder.mjs +0 -6
  108. package/dist/lib/conformance/seeder.mjs.map +1 -1
  109. package/dist/lib/conformance/types.mjs +0 -6
  110. package/dist/lib/conformance/types.mjs.map +1 -1
  111. package/dist/lib/conformance/webhook.mjs +0 -6
  112. package/dist/lib/conformance/webhook.mjs.map +1 -1
  113. package/dist/lib/core/ADCPMultiAgentClient.mjs +0 -6
  114. package/dist/lib/core/ADCPMultiAgentClient.mjs.map +1 -1
  115. package/dist/lib/core/AgentClient.mjs +0 -6
  116. package/dist/lib/core/AgentClient.mjs.map +1 -1
  117. package/dist/lib/core/AsyncHandler.mjs +0 -6
  118. package/dist/lib/core/AsyncHandler.mjs.map +1 -1
  119. package/dist/lib/core/ConfigurationManager.mjs +0 -6
  120. package/dist/lib/core/ConfigurationManager.mjs.map +1 -1
  121. package/dist/lib/core/ConversationTypes.mjs +0 -6
  122. package/dist/lib/core/CreativeAgentClient.mjs +0 -6
  123. package/dist/lib/core/CreativeAgentClient.mjs.map +1 -1
  124. package/dist/lib/core/GovernanceMiddleware.mjs +0 -6
  125. package/dist/lib/core/GovernanceMiddleware.mjs.map +1 -1
  126. package/dist/lib/core/GovernanceTypes.mjs +0 -6
  127. package/dist/lib/core/GovernanceTypes.mjs.map +1 -1
  128. package/dist/lib/core/ProtocolResponseParser.mjs +0 -6
  129. package/dist/lib/core/ProtocolResponseParser.mjs.map +1 -1
  130. package/dist/lib/core/ResponseValidator.mjs +0 -6
  131. package/dist/lib/core/ResponseValidator.mjs.map +1 -1
  132. package/dist/lib/core/SingleAgentClient.mjs +0 -6
  133. package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
  134. package/dist/lib/core/TaskEventTypes.mjs +0 -6
  135. package/dist/lib/core/TaskEventTypes.mjs.map +1 -1
  136. package/dist/lib/core/TaskExecutor.mjs +0 -6
  137. package/dist/lib/core/TaskExecutor.mjs.map +1 -1
  138. package/dist/lib/core/match.mjs +0 -6
  139. package/dist/lib/core/match.mjs.map +1 -1
  140. package/dist/lib/core/task-status.mjs +0 -6
  141. package/dist/lib/core/task-status.mjs.map +1 -1
  142. package/dist/lib/core/webhook-url.mjs +0 -6
  143. package/dist/lib/core/webhook-url.mjs.map +1 -1
  144. package/dist/lib/discovery/adagents-redirects.mjs +0 -6
  145. package/dist/lib/discovery/adagents-redirects.mjs.map +1 -1
  146. package/dist/lib/discovery/agent-directory.mjs +0 -6
  147. package/dist/lib/discovery/agent-directory.mjs.map +1 -1
  148. package/dist/lib/discovery/inline-publisher-properties.mjs +0 -6
  149. package/dist/lib/discovery/inline-publisher-properties.mjs.map +1 -1
  150. package/dist/lib/discovery/network-consistency-checker.mjs +0 -6
  151. package/dist/lib/discovery/network-consistency-checker.mjs.map +1 -1
  152. package/dist/lib/discovery/property-crawler.mjs +0 -6
  153. package/dist/lib/discovery/property-crawler.mjs.map +1 -1
  154. package/dist/lib/discovery/property-index.mjs +0 -6
  155. package/dist/lib/discovery/property-index.mjs.map +1 -1
  156. package/dist/lib/discovery/publisher-property-selector.mjs +0 -6
  157. package/dist/lib/discovery/publisher-property-selector.mjs.map +1 -1
  158. package/dist/lib/discovery/resolve-agent-properties.mjs +0 -6
  159. package/dist/lib/discovery/resolve-agent-properties.mjs.map +1 -1
  160. package/dist/lib/discovery/types.mjs +0 -6
  161. package/dist/lib/discovery/validate-adagents.mjs +0 -6
  162. package/dist/lib/discovery/validate-adagents.mjs.map +1 -1
  163. package/dist/lib/enums.mjs +0 -6
  164. package/dist/lib/enums.mjs.map +1 -1
  165. package/dist/lib/errors/index.mjs +0 -6
  166. package/dist/lib/errors/index.mjs.map +1 -1
  167. package/dist/lib/express-mcp/index.mjs +0 -6
  168. package/dist/lib/express-mcp/index.mjs.map +1 -1
  169. package/dist/lib/governance/index.mjs +0 -6
  170. package/dist/lib/governance/index.mjs.map +1 -1
  171. package/dist/lib/handlers/types.mjs +0 -6
  172. package/dist/lib/handlers/types.mjs.map +1 -1
  173. package/dist/lib/index.d.mts +1 -1
  174. package/dist/lib/index.d.ts +1 -1
  175. package/dist/lib/index.d.ts.map +1 -1
  176. package/dist/lib/index.js.map +1 -1
  177. package/dist/lib/index.mjs +0 -6
  178. package/dist/lib/index.mjs.map +1 -1
  179. package/dist/lib/media-buy/available-actions.mjs +0 -6
  180. package/dist/lib/media-buy/available-actions.mjs.map +1 -1
  181. package/dist/lib/media-buy/index.mjs +0 -6
  182. package/dist/lib/media-buy/index.mjs.map +1 -1
  183. package/dist/lib/media-buy/preflight.mjs +0 -6
  184. package/dist/lib/media-buy/preflight.mjs.map +1 -1
  185. package/dist/lib/media-buy/property-policy.mjs +0 -6
  186. package/dist/lib/media-buy/property-policy.mjs.map +1 -1
  187. package/dist/lib/media-buy/types.mjs +0 -6
  188. package/dist/lib/media-buy/types.mjs.map +1 -1
  189. package/dist/lib/media-buy/update-fields.generated.mjs +0 -6
  190. package/dist/lib/media-buy/update-fields.generated.mjs.map +1 -1
  191. package/dist/lib/mock-server/creative-ad-server/seed-data.mjs +0 -6
  192. package/dist/lib/mock-server/creative-ad-server/seed-data.mjs.map +1 -1
  193. package/dist/lib/mock-server/creative-ad-server/server.mjs +0 -6
  194. package/dist/lib/mock-server/creative-ad-server/server.mjs.map +1 -1
  195. package/dist/lib/mock-server/creative-template/seed-data.mjs +0 -6
  196. package/dist/lib/mock-server/creative-template/seed-data.mjs.map +1 -1
  197. package/dist/lib/mock-server/creative-template/server.mjs +0 -6
  198. package/dist/lib/mock-server/creative-template/server.mjs.map +1 -1
  199. package/dist/lib/mock-server/index.mjs +0 -6
  200. package/dist/lib/mock-server/index.mjs.map +1 -1
  201. package/dist/lib/mock-server/sales-guaranteed/recipe.mjs +0 -6
  202. package/dist/lib/mock-server/sales-guaranteed/recipe.mjs.map +1 -1
  203. package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs +0 -6
  204. package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs.map +1 -1
  205. package/dist/lib/mock-server/sales-guaranteed/server.mjs +0 -6
  206. package/dist/lib/mock-server/sales-guaranteed/server.mjs.map +1 -1
  207. package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs +0 -6
  208. package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs.map +1 -1
  209. package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs +0 -6
  210. package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs.map +1 -1
  211. package/dist/lib/mock-server/sales-non-guaranteed/server.mjs +0 -6
  212. package/dist/lib/mock-server/sales-non-guaranteed/server.mjs.map +1 -1
  213. package/dist/lib/mock-server/sales-social/seed-data.mjs +0 -6
  214. package/dist/lib/mock-server/sales-social/seed-data.mjs.map +1 -1
  215. package/dist/lib/mock-server/sales-social/server.mjs +0 -6
  216. package/dist/lib/mock-server/sales-social/server.mjs.map +1 -1
  217. package/dist/lib/mock-server/scenario.mjs +0 -6
  218. package/dist/lib/mock-server/scenario.mjs.map +1 -1
  219. package/dist/lib/mock-server/signal-marketplace/seed-data.mjs +0 -6
  220. package/dist/lib/mock-server/signal-marketplace/seed-data.mjs.map +1 -1
  221. package/dist/lib/mock-server/signal-marketplace/server.mjs +0 -6
  222. package/dist/lib/mock-server/signal-marketplace/server.mjs.map +1 -1
  223. package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs +0 -6
  224. package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs.map +1 -1
  225. package/dist/lib/mock-server/sponsored-intelligence/server.mjs +0 -6
  226. package/dist/lib/mock-server/sponsored-intelligence/server.mjs.map +1 -1
  227. package/dist/lib/net/address-guards.mjs +0 -6
  228. package/dist/lib/net/address-guards.mjs.map +1 -1
  229. package/dist/lib/net/index.mjs +0 -6
  230. package/dist/lib/net/index.mjs.map +1 -1
  231. package/dist/lib/net/ssrf-fetch.mjs +0 -6
  232. package/dist/lib/net/ssrf-fetch.mjs.map +1 -1
  233. package/dist/lib/observability/index.mjs +0 -6
  234. package/dist/lib/observability/index.mjs.map +1 -1
  235. package/dist/lib/observability/tracing.mjs +6 -7
  236. package/dist/lib/observability/tracing.mjs.map +1 -1
  237. package/dist/lib/protocols/a2a.mjs +0 -6
  238. package/dist/lib/protocols/a2a.mjs.map +1 -1
  239. package/dist/lib/protocols/abort.mjs +0 -6
  240. package/dist/lib/protocols/abort.mjs.map +1 -1
  241. package/dist/lib/protocols/index.mjs +0 -6
  242. package/dist/lib/protocols/index.mjs.map +1 -1
  243. package/dist/lib/protocols/mcp-modern.mjs +0 -6
  244. package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
  245. package/dist/lib/protocols/mcp-tasks.mjs +0 -6
  246. package/dist/lib/protocols/mcp-tasks.mjs.map +1 -1
  247. package/dist/lib/protocols/mcp.mjs +0 -6
  248. package/dist/lib/protocols/mcp.mjs.map +1 -1
  249. package/dist/lib/protocols/rawResponseCapture.mjs +0 -6
  250. package/dist/lib/protocols/rawResponseCapture.mjs.map +1 -1
  251. package/dist/lib/protocols/responseSizeLimit.mjs +0 -6
  252. package/dist/lib/protocols/responseSizeLimit.mjs.map +1 -1
  253. package/dist/lib/protocols/transportDiagnostics.mjs +0 -6
  254. package/dist/lib/protocols/transportDiagnostics.mjs.map +1 -1
  255. package/dist/lib/registry/cursor-store.mjs +0 -6
  256. package/dist/lib/registry/cursor-store.mjs.map +1 -1
  257. package/dist/lib/registry/feed-stream.mjs +0 -6
  258. package/dist/lib/registry/feed-stream.mjs.map +1 -1
  259. package/dist/lib/registry/index.mjs +0 -6
  260. package/dist/lib/registry/index.mjs.map +1 -1
  261. package/dist/lib/registry/property-registry.mjs +0 -6
  262. package/dist/lib/registry/property-registry.mjs.map +1 -1
  263. package/dist/lib/registry/sync.mjs +0 -6
  264. package/dist/lib/registry/sync.mjs.map +1 -1
  265. package/dist/lib/registry/types.generated.mjs +0 -6
  266. package/dist/lib/registry/types.mjs +0 -6
  267. package/dist/lib/schemas/index.mjs +0 -6
  268. package/dist/lib/schemas/index.mjs.map +1 -1
  269. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  270. package/dist/lib/server/a2a-adapter.mjs +0 -6
  271. package/dist/lib/server/a2a-adapter.mjs.map +1 -1
  272. package/dist/lib/server/account-mode.mjs +0 -6
  273. package/dist/lib/server/account-mode.mjs.map +1 -1
  274. package/dist/lib/server/adcp-server.mjs +0 -6
  275. package/dist/lib/server/adcp-server.mjs.map +1 -1
  276. package/dist/lib/server/auth-introspection.mjs +0 -6
  277. package/dist/lib/server/auth-introspection.mjs.map +1 -1
  278. package/dist/lib/server/auth-signature.mjs +0 -6
  279. package/dist/lib/server/auth-signature.mjs.map +1 -1
  280. package/dist/lib/server/auth.mjs +0 -6
  281. package/dist/lib/server/auth.mjs.map +1 -1
  282. package/dist/lib/server/create-adcp-server.d.mts +13 -0
  283. package/dist/lib/server/create-adcp-server.d.ts +13 -0
  284. package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
  285. package/dist/lib/server/create-adcp-server.js +3 -2
  286. package/dist/lib/server/create-adcp-server.js.map +1 -1
  287. package/dist/lib/server/create-adcp-server.mjs +3 -8
  288. package/dist/lib/server/create-adcp-server.mjs.map +1 -1
  289. package/dist/lib/server/credential-policy.mjs +0 -6
  290. package/dist/lib/server/credential-policy.mjs.map +1 -1
  291. package/dist/lib/server/ctx-metadata/backends/memory.mjs +0 -6
  292. package/dist/lib/server/ctx-metadata/backends/memory.mjs.map +1 -1
  293. package/dist/lib/server/ctx-metadata/backends/pg.mjs +0 -6
  294. package/dist/lib/server/ctx-metadata/backends/pg.mjs.map +1 -1
  295. package/dist/lib/server/ctx-metadata/backends/redis.mjs +0 -6
  296. package/dist/lib/server/ctx-metadata/backends/redis.mjs.map +1 -1
  297. package/dist/lib/server/ctx-metadata/index.mjs +0 -6
  298. package/dist/lib/server/ctx-metadata/index.mjs.map +1 -1
  299. package/dist/lib/server/ctx-metadata/store.mjs +0 -6
  300. package/dist/lib/server/ctx-metadata/store.mjs.map +1 -1
  301. package/dist/lib/server/ctx-metadata/wire-shape.mjs +0 -6
  302. package/dist/lib/server/ctx-metadata/wire-shape.mjs.map +1 -1
  303. package/dist/lib/server/decisioning/account.mjs +0 -6
  304. package/dist/lib/server/decisioning/account.mjs.map +1 -1
  305. package/dist/lib/server/decisioning/admin-router.mjs +0 -6
  306. package/dist/lib/server/decisioning/admin-router.mjs.map +1 -1
  307. package/dist/lib/server/decisioning/assembly-helpers.mjs +0 -6
  308. package/dist/lib/server/decisioning/assembly-helpers.mjs.map +1 -1
  309. package/dist/lib/server/decisioning/async-outcome.mjs +0 -6
  310. package/dist/lib/server/decisioning/async-outcome.mjs.map +1 -1
  311. package/dist/lib/server/decisioning/buyer-agent.mjs +0 -6
  312. package/dist/lib/server/decisioning/buyer-agent.mjs.map +1 -1
  313. package/dist/lib/server/decisioning/capabilities.mjs +0 -6
  314. package/dist/lib/server/decisioning/capabilities.mjs.map +1 -1
  315. package/dist/lib/server/decisioning/compose.mjs +0 -6
  316. package/dist/lib/server/decisioning/compose.mjs.map +1 -1
  317. package/dist/lib/server/decisioning/context.mjs +0 -6
  318. package/dist/lib/server/decisioning/errors-typed.mjs +0 -6
  319. package/dist/lib/server/decisioning/errors-typed.mjs.map +1 -1
  320. package/dist/lib/server/decisioning/helpers.mjs +0 -6
  321. package/dist/lib/server/decisioning/helpers.mjs.map +1 -1
  322. package/dist/lib/server/decisioning/index.mjs +0 -6
  323. package/dist/lib/server/decisioning/index.mjs.map +1 -1
  324. package/dist/lib/server/decisioning/list-helpers.mjs +0 -6
  325. package/dist/lib/server/decisioning/list-helpers.mjs.map +1 -1
  326. package/dist/lib/server/decisioning/manifest-helpers.mjs +0 -6
  327. package/dist/lib/server/decisioning/manifest-helpers.mjs.map +1 -1
  328. package/dist/lib/server/decisioning/pagination.mjs +0 -6
  329. package/dist/lib/server/decisioning/platform-helpers.mjs +0 -6
  330. package/dist/lib/server/decisioning/platform-helpers.mjs.map +1 -1
  331. package/dist/lib/server/decisioning/platform.mjs +0 -6
  332. package/dist/lib/server/decisioning/proposal/dispatch.mjs +0 -6
  333. package/dist/lib/server/decisioning/proposal/dispatch.mjs.map +1 -1
  334. package/dist/lib/server/decisioning/proposal/index.mjs +0 -6
  335. package/dist/lib/server/decisioning/proposal/index.mjs.map +1 -1
  336. package/dist/lib/server/decisioning/proposal/lifecycle.mjs +0 -6
  337. package/dist/lib/server/decisioning/proposal/lifecycle.mjs.map +1 -1
  338. package/dist/lib/server/decisioning/proposal/mock-manager.mjs +0 -6
  339. package/dist/lib/server/decisioning/proposal/mock-manager.mjs.map +1 -1
  340. package/dist/lib/server/decisioning/proposal/store.mjs +0 -6
  341. package/dist/lib/server/decisioning/proposal/store.mjs.map +1 -1
  342. package/dist/lib/server/decisioning/proposal/types.mjs +0 -6
  343. package/dist/lib/server/decisioning/proposal/types.mjs.map +1 -1
  344. package/dist/lib/server/decisioning/resolve-presets.mjs +0 -6
  345. package/dist/lib/server/decisioning/resolve-presets.mjs.map +1 -1
  346. package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs +0 -6
  347. package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs.map +1 -1
  348. package/dist/lib/server/decisioning/runtime/from-platform.mjs +0 -6
  349. package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
  350. package/dist/lib/server/decisioning/runtime/observed-modes.mjs +0 -6
  351. package/dist/lib/server/decisioning/runtime/observed-modes.mjs.map +1 -1
  352. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +0 -6
  353. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs.map +1 -1
  354. package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs +0 -6
  355. package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs.map +1 -1
  356. package/dist/lib/server/decisioning/runtime/task-registry.mjs +0 -6
  357. package/dist/lib/server/decisioning/runtime/task-registry.mjs.map +1 -1
  358. package/dist/lib/server/decisioning/runtime/to-context.mjs +0 -6
  359. package/dist/lib/server/decisioning/runtime/to-context.mjs.map +1 -1
  360. package/dist/lib/server/decisioning/runtime/validate-platform.mjs +0 -6
  361. package/dist/lib/server/decisioning/runtime/validate-platform.mjs.map +1 -1
  362. package/dist/lib/server/decisioning/specialisms/audiences.mjs +0 -6
  363. package/dist/lib/server/decisioning/specialisms/brand-rights.mjs +0 -6
  364. package/dist/lib/server/decisioning/specialisms/campaign-governance.mjs +0 -6
  365. package/dist/lib/server/decisioning/specialisms/content-standards.mjs +0 -6
  366. package/dist/lib/server/decisioning/specialisms/creative-ad-server.mjs +0 -6
  367. package/dist/lib/server/decisioning/specialisms/creative.mjs +0 -6
  368. package/dist/lib/server/decisioning/specialisms/lists.mjs +0 -6
  369. package/dist/lib/server/decisioning/specialisms/sales.mjs +0 -6
  370. package/dist/lib/server/decisioning/specialisms/signals.mjs +0 -6
  371. package/dist/lib/server/decisioning/specialisms/sponsored-intelligence.mjs +0 -6
  372. package/dist/lib/server/decisioning/start-time.mjs +0 -6
  373. package/dist/lib/server/decisioning/start-time.mjs.map +1 -1
  374. package/dist/lib/server/decisioning/status-changes.mjs +0 -6
  375. package/dist/lib/server/decisioning/status-changes.mjs.map +1 -1
  376. package/dist/lib/server/decisioning/status-mappers.mjs +0 -6
  377. package/dist/lib/server/decisioning/status-mappers.mjs.map +1 -1
  378. package/dist/lib/server/decisioning/tenant-registry.mjs +0 -6
  379. package/dist/lib/server/decisioning/tenant-registry.mjs.map +1 -1
  380. package/dist/lib/server/decisioning/tenant-store.mjs +0 -6
  381. package/dist/lib/server/decisioning/tenant-store.mjs.map +1 -1
  382. package/dist/lib/server/decisioning/validate-specialisms.mjs +0 -6
  383. package/dist/lib/server/decisioning/validate-specialisms.mjs.map +1 -1
  384. package/dist/lib/server/dynamic-registry.mjs +0 -6
  385. package/dist/lib/server/dynamic-registry.mjs.map +1 -1
  386. package/dist/lib/server/envelope-allowlist.mjs +0 -6
  387. package/dist/lib/server/envelope-allowlist.mjs.map +1 -1
  388. package/dist/lib/server/error-arm-tools.mjs +5 -6
  389. package/dist/lib/server/error-arm-tools.mjs.map +1 -1
  390. package/dist/lib/server/errors.mjs +0 -6
  391. package/dist/lib/server/errors.mjs.map +1 -1
  392. package/dist/lib/server/example-tld-guard.mjs +0 -6
  393. package/dist/lib/server/example-tld-guard.mjs.map +1 -1
  394. package/dist/lib/server/express-adapter.mjs +0 -6
  395. package/dist/lib/server/express-adapter.mjs.map +1 -1
  396. package/dist/lib/server/governance.mjs +0 -6
  397. package/dist/lib/server/governance.mjs.map +1 -1
  398. package/dist/lib/server/idempotency/backends/lazy.mjs +0 -6
  399. package/dist/lib/server/idempotency/backends/lazy.mjs.map +1 -1
  400. package/dist/lib/server/idempotency/backends/memory.mjs +0 -6
  401. package/dist/lib/server/idempotency/backends/memory.mjs.map +1 -1
  402. package/dist/lib/server/idempotency/backends/pg.mjs +0 -6
  403. package/dist/lib/server/idempotency/backends/pg.mjs.map +1 -1
  404. package/dist/lib/server/idempotency/backends/redis.mjs +0 -6
  405. package/dist/lib/server/idempotency/backends/redis.mjs.map +1 -1
  406. package/dist/lib/server/idempotency/index.mjs +0 -6
  407. package/dist/lib/server/idempotency/index.mjs.map +1 -1
  408. package/dist/lib/server/idempotency/store.mjs +0 -6
  409. package/dist/lib/server/idempotency/store.mjs.map +1 -1
  410. package/dist/lib/server/index.d.mts +1 -1
  411. package/dist/lib/server/index.d.ts +1 -1
  412. package/dist/lib/server/index.d.ts.map +1 -1
  413. package/dist/lib/server/index.js.map +1 -1
  414. package/dist/lib/server/index.mjs +0 -6
  415. package/dist/lib/server/index.mjs.map +1 -1
  416. package/dist/lib/server/legacy/v5/index.d.mts +1 -1
  417. package/dist/lib/server/legacy/v5/index.d.ts +1 -1
  418. package/dist/lib/server/legacy/v5/index.d.ts.map +1 -1
  419. package/dist/lib/server/legacy/v5/index.js.map +1 -1
  420. package/dist/lib/server/legacy/v5/index.mjs +0 -6
  421. package/dist/lib/server/legacy/v5/index.mjs.map +1 -1
  422. package/dist/lib/server/mcp-modern-server.mjs +0 -6
  423. package/dist/lib/server/mcp-modern-server.mjs.map +1 -1
  424. package/dist/lib/server/media-buy-actions.mjs +0 -6
  425. package/dist/lib/server/media-buy-actions.mjs.map +1 -1
  426. package/dist/lib/server/media-buy-helpers.mjs +0 -6
  427. package/dist/lib/server/media-buy-helpers.mjs.map +1 -1
  428. package/dist/lib/server/media-buy-store.mjs +0 -6
  429. package/dist/lib/server/media-buy-store.mjs.map +1 -1
  430. package/dist/lib/server/normalize-errors.mjs +0 -6
  431. package/dist/lib/server/normalize-errors.mjs.map +1 -1
  432. package/dist/lib/server/operational-platform.mjs +0 -6
  433. package/dist/lib/server/operational-platform.mjs.map +1 -1
  434. package/dist/lib/server/pick-safe-details.mjs +0 -6
  435. package/dist/lib/server/pick-safe-details.mjs.map +1 -1
  436. package/dist/lib/server/pin-and-bind-fetch.mjs +0 -6
  437. package/dist/lib/server/pin-and-bind-fetch.mjs.map +1 -1
  438. package/dist/lib/server/postgres-state-store.mjs +0 -6
  439. package/dist/lib/server/postgres-state-store.mjs.map +1 -1
  440. package/dist/lib/server/postgres-task-store.mjs +0 -6
  441. package/dist/lib/server/postgres-task-store.mjs.map +1 -1
  442. package/dist/lib/server/product-defaults.mjs +0 -6
  443. package/dist/lib/server/product-defaults.mjs.map +1 -1
  444. package/dist/lib/server/redact.mjs +0 -6
  445. package/dist/lib/server/redact.mjs.map +1 -1
  446. package/dist/lib/server/responses.mjs +0 -6
  447. package/dist/lib/server/responses.mjs.map +1 -1
  448. package/dist/lib/server/serve.mjs +0 -6
  449. package/dist/lib/server/serve.mjs.map +1 -1
  450. package/dist/lib/server/socket-mode/conformance-client.mjs +0 -6
  451. package/dist/lib/server/socket-mode/conformance-client.mjs.map +1 -1
  452. package/dist/lib/server/socket-mode/index.mjs +0 -6
  453. package/dist/lib/server/socket-mode/index.mjs.map +1 -1
  454. package/dist/lib/server/socket-mode/ws-transport.mjs +0 -6
  455. package/dist/lib/server/socket-mode/ws-transport.mjs.map +1 -1
  456. package/dist/lib/server/state-machine.mjs +0 -6
  457. package/dist/lib/server/state-machine.mjs.map +1 -1
  458. package/dist/lib/server/state-store.mjs +0 -6
  459. package/dist/lib/server/state-store.mjs.map +1 -1
  460. package/dist/lib/server/structured-serialize.mjs +0 -6
  461. package/dist/lib/server/structured-serialize.mjs.map +1 -1
  462. package/dist/lib/server/targeting-helpers.mjs +0 -6
  463. package/dist/lib/server/targeting-helpers.mjs.map +1 -1
  464. package/dist/lib/server/tasks.mjs +0 -6
  465. package/dist/lib/server/tasks.mjs.map +1 -1
  466. package/dist/lib/server/test-controller-bridge.mjs +0 -6
  467. package/dist/lib/server/test-controller-bridge.mjs.map +1 -1
  468. package/dist/lib/server/test-controller.mjs +0 -6
  469. package/dist/lib/server/test-controller.mjs.map +1 -1
  470. package/dist/lib/server/upstream-helpers.mjs +0 -6
  471. package/dist/lib/server/upstream-helpers.mjs.map +1 -1
  472. package/dist/lib/server/webhook-emitter.mjs +0 -6
  473. package/dist/lib/server/webhook-emitter.mjs.map +1 -1
  474. package/dist/lib/server/wire-safe.mjs +0 -6
  475. package/dist/lib/server/wire-safe.mjs.map +1 -1
  476. package/dist/lib/server/wire-spec-fields.generated.mjs +0 -6
  477. package/dist/lib/server/wire-spec-fields.generated.mjs.map +1 -1
  478. package/dist/lib/server/wrap-envelope.mjs +0 -6
  479. package/dist/lib/server/wrap-envelope.mjs.map +1 -1
  480. package/dist/lib/signing/agent-context.mjs +0 -6
  481. package/dist/lib/signing/agent-context.mjs.map +1 -1
  482. package/dist/lib/signing/agent-fetch.mjs +0 -6
  483. package/dist/lib/signing/agent-fetch.mjs.map +1 -1
  484. package/dist/lib/signing/agent-resolver/canonicalize.mjs +0 -6
  485. package/dist/lib/signing/agent-resolver/canonicalize.mjs.map +1 -1
  486. package/dist/lib/signing/agent-resolver/capabilities-types.mjs +0 -6
  487. package/dist/lib/signing/agent-resolver/capabilities-types.mjs.map +1 -1
  488. package/dist/lib/signing/agent-resolver/consistency.mjs +0 -6
  489. package/dist/lib/signing/agent-resolver/consistency.mjs.map +1 -1
  490. package/dist/lib/signing/agent-resolver/errors.mjs +0 -6
  491. package/dist/lib/signing/agent-resolver/errors.mjs.map +1 -1
  492. package/dist/lib/signing/agent-resolver/etld.mjs +0 -6
  493. package/dist/lib/signing/agent-resolver/etld.mjs.map +1 -1
  494. package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +0 -6
  495. package/dist/lib/signing/agent-resolver/fetch-helpers.mjs.map +1 -1
  496. package/dist/lib/signing/agent-resolver/index.mjs +0 -6
  497. package/dist/lib/signing/agent-resolver/index.mjs.map +1 -1
  498. package/dist/lib/signing/agent-resolver/jwks-set.mjs +0 -6
  499. package/dist/lib/signing/agent-resolver/jwks-set.mjs.map +1 -1
  500. package/dist/lib/signing/agent-resolver/resolve-agent.mjs +0 -6
  501. package/dist/lib/signing/agent-resolver/resolve-agent.mjs.map +1 -1
  502. package/dist/lib/signing/agent-resolver/select-agent.mjs +0 -6
  503. package/dist/lib/signing/agent-resolver/select-agent.mjs.map +1 -1
  504. package/dist/lib/signing/agent-resolver/strict-json.mjs +0 -6
  505. package/dist/lib/signing/agent-resolver/strict-json.mjs.map +1 -1
  506. package/dist/lib/signing/brand-jwks.mjs +0 -6
  507. package/dist/lib/signing/brand-jwks.mjs.map +1 -1
  508. package/dist/lib/signing/canonicalize.mjs +0 -6
  509. package/dist/lib/signing/canonicalize.mjs.map +1 -1
  510. package/dist/lib/signing/capability-cache.mjs +0 -6
  511. package/dist/lib/signing/capability-cache.mjs.map +1 -1
  512. package/dist/lib/signing/capability-priming.mjs +0 -6
  513. package/dist/lib/signing/capability-priming.mjs.map +1 -1
  514. package/dist/lib/signing/client.mjs +0 -6
  515. package/dist/lib/signing/client.mjs.map +1 -1
  516. package/dist/lib/signing/content-digest.mjs +0 -6
  517. package/dist/lib/signing/content-digest.mjs.map +1 -1
  518. package/dist/lib/signing/crypto.mjs +0 -6
  519. package/dist/lib/signing/crypto.mjs.map +1 -1
  520. package/dist/lib/signing/ecdsa-encoding.mjs +0 -6
  521. package/dist/lib/signing/ecdsa-encoding.mjs.map +1 -1
  522. package/dist/lib/signing/errors.mjs +0 -6
  523. package/dist/lib/signing/errors.mjs.map +1 -1
  524. package/dist/lib/signing/fetch-async.mjs +0 -6
  525. package/dist/lib/signing/fetch-async.mjs.map +1 -1
  526. package/dist/lib/signing/fetch.mjs +0 -6
  527. package/dist/lib/signing/fetch.mjs.map +1 -1
  528. package/dist/lib/signing/index.mjs +0 -6
  529. package/dist/lib/signing/index.mjs.map +1 -1
  530. package/dist/lib/signing/jwks-helpers.mjs +0 -6
  531. package/dist/lib/signing/jwks-helpers.mjs.map +1 -1
  532. package/dist/lib/signing/jwks-https.mjs +0 -6
  533. package/dist/lib/signing/jwks-https.mjs.map +1 -1
  534. package/dist/lib/signing/jwks.mjs +0 -6
  535. package/dist/lib/signing/jwks.mjs.map +1 -1
  536. package/dist/lib/signing/middleware.mjs +0 -6
  537. package/dist/lib/signing/middleware.mjs.map +1 -1
  538. package/dist/lib/signing/parser.mjs +0 -6
  539. package/dist/lib/signing/parser.mjs.map +1 -1
  540. package/dist/lib/signing/postgres-replay-store.mjs +0 -6
  541. package/dist/lib/signing/postgres-replay-store.mjs.map +1 -1
  542. package/dist/lib/signing/protocol-response.mjs +0 -6
  543. package/dist/lib/signing/protocol-response.mjs.map +1 -1
  544. package/dist/lib/signing/provider.mjs +0 -6
  545. package/dist/lib/signing/redis-replay-store.mjs +0 -6
  546. package/dist/lib/signing/redis-replay-store.mjs.map +1 -1
  547. package/dist/lib/signing/replay.mjs +0 -6
  548. package/dist/lib/signing/replay.mjs.map +1 -1
  549. package/dist/lib/signing/request-context.mjs +0 -6
  550. package/dist/lib/signing/request-context.mjs.map +1 -1
  551. package/dist/lib/signing/revocation-https.mjs +0 -6
  552. package/dist/lib/signing/revocation-https.mjs.map +1 -1
  553. package/dist/lib/signing/revocation.mjs +0 -6
  554. package/dist/lib/signing/revocation.mjs.map +1 -1
  555. package/dist/lib/signing/server.mjs +0 -6
  556. package/dist/lib/signing/server.mjs.map +1 -1
  557. package/dist/lib/signing/signer-async.mjs +0 -6
  558. package/dist/lib/signing/signer-async.mjs.map +1 -1
  559. package/dist/lib/signing/signer.mjs +0 -6
  560. package/dist/lib/signing/signer.mjs.map +1 -1
  561. package/dist/lib/signing/testing.mjs +0 -6
  562. package/dist/lib/signing/testing.mjs.map +1 -1
  563. package/dist/lib/signing/types.mjs +0 -6
  564. package/dist/lib/signing/types.mjs.map +1 -1
  565. package/dist/lib/signing/verifier.mjs +0 -6
  566. package/dist/lib/signing/verifier.mjs.map +1 -1
  567. package/dist/lib/signing/webhook-auth-detection.mjs +0 -6
  568. package/dist/lib/signing/webhook-auth-detection.mjs.map +1 -1
  569. package/dist/lib/signing/webhook-verifier.mjs +0 -6
  570. package/dist/lib/signing/webhook-verifier.mjs.map +1 -1
  571. package/dist/lib/storage/MemoryStorage.mjs +0 -6
  572. package/dist/lib/storage/MemoryStorage.mjs.map +1 -1
  573. package/dist/lib/storage/interfaces.mjs +0 -6
  574. package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs +0 -6
  575. package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs.map +1 -1
  576. package/dist/lib/substitution/encoder/index.mjs +0 -6
  577. package/dist/lib/substitution/encoder/index.mjs.map +1 -1
  578. package/dist/lib/substitution/index.mjs +0 -6
  579. package/dist/lib/substitution/index.mjs.map +1 -1
  580. package/dist/lib/substitution/observer/SubstitutionObserver.mjs +0 -6
  581. package/dist/lib/substitution/observer/SubstitutionObserver.mjs.map +1 -1
  582. package/dist/lib/substitution/observer/alignment.mjs +0 -6
  583. package/dist/lib/substitution/observer/alignment.mjs.map +1 -1
  584. package/dist/lib/substitution/observer/assertions.mjs +0 -6
  585. package/dist/lib/substitution/observer/assertions.mjs.map +1 -1
  586. package/dist/lib/substitution/observer/html-parser.mjs +0 -6
  587. package/dist/lib/substitution/observer/html-parser.mjs.map +1 -1
  588. package/dist/lib/substitution/observer/index.mjs +0 -6
  589. package/dist/lib/substitution/observer/index.mjs.map +1 -1
  590. package/dist/lib/substitution/observer/ssrf.mjs +0 -6
  591. package/dist/lib/substitution/observer/ssrf.mjs.map +1 -1
  592. package/dist/lib/substitution/rfc3986.mjs +0 -6
  593. package/dist/lib/substitution/rfc3986.mjs.map +1 -1
  594. package/dist/lib/substitution/translate.mjs +0 -6
  595. package/dist/lib/substitution/translate.mjs.map +1 -1
  596. package/dist/lib/substitution/types.mjs +0 -6
  597. package/dist/lib/substitution/vectors.mjs +0 -6
  598. package/dist/lib/substitution/vectors.mjs.map +1 -1
  599. package/dist/lib/testing/agent-tester.mjs +0 -6
  600. package/dist/lib/testing/agent-tester.mjs.map +1 -1
  601. package/dist/lib/testing/client.mjs +0 -6
  602. package/dist/lib/testing/client.mjs.map +1 -1
  603. package/dist/lib/testing/compliance/briefs.mjs +0 -6
  604. package/dist/lib/testing/compliance/briefs.mjs.map +1 -1
  605. package/dist/lib/testing/compliance/comply.mjs +0 -6
  606. package/dist/lib/testing/compliance/comply.mjs.map +1 -1
  607. package/dist/lib/testing/compliance/index.mjs +0 -6
  608. package/dist/lib/testing/compliance/index.mjs.map +1 -1
  609. package/dist/lib/testing/compliance/spec-conformance.mjs +0 -6
  610. package/dist/lib/testing/compliance/spec-conformance.mjs.map +1 -1
  611. package/dist/lib/testing/compliance/storyboard-tracks.mjs +0 -6
  612. package/dist/lib/testing/compliance/storyboard-tracks.mjs.map +1 -1
  613. package/dist/lib/testing/compliance/summary.mjs +0 -6
  614. package/dist/lib/testing/compliance/summary.mjs.map +1 -1
  615. package/dist/lib/testing/compliance/types.mjs +0 -6
  616. package/dist/lib/testing/comply-controller.mjs +0 -6
  617. package/dist/lib/testing/comply-controller.mjs.map +1 -1
  618. package/dist/lib/testing/controller-assertions.mjs +0 -6
  619. package/dist/lib/testing/controller-assertions.mjs.map +1 -1
  620. package/dist/lib/testing/formatter.mjs +0 -6
  621. package/dist/lib/testing/formatter.mjs.map +1 -1
  622. package/dist/lib/testing/index.mjs +0 -6
  623. package/dist/lib/testing/index.mjs.map +1 -1
  624. package/dist/lib/testing/local-agent-runner.mjs +0 -6
  625. package/dist/lib/testing/local-agent-runner.mjs.map +1 -1
  626. package/dist/lib/testing/orchestrator.mjs +0 -6
  627. package/dist/lib/testing/orchestrator.mjs.map +1 -1
  628. package/dist/lib/testing/personas/index.mjs +0 -6
  629. package/dist/lib/testing/personas/index.mjs.map +1 -1
  630. package/dist/lib/testing/scenarios/brand-rights.mjs +0 -6
  631. package/dist/lib/testing/scenarios/brand-rights.mjs.map +1 -1
  632. package/dist/lib/testing/scenarios/capabilities.mjs +0 -6
  633. package/dist/lib/testing/scenarios/capabilities.mjs.map +1 -1
  634. package/dist/lib/testing/scenarios/creative.mjs +0 -6
  635. package/dist/lib/testing/scenarios/creative.mjs.map +1 -1
  636. package/dist/lib/testing/scenarios/deterministic.mjs +0 -6
  637. package/dist/lib/testing/scenarios/deterministic.mjs.map +1 -1
  638. package/dist/lib/testing/scenarios/discovery.mjs +0 -6
  639. package/dist/lib/testing/scenarios/discovery.mjs.map +1 -1
  640. package/dist/lib/testing/scenarios/edge-cases.mjs +0 -6
  641. package/dist/lib/testing/scenarios/edge-cases.mjs.map +1 -1
  642. package/dist/lib/testing/scenarios/error-compliance.mjs +0 -6
  643. package/dist/lib/testing/scenarios/error-compliance.mjs.map +1 -1
  644. package/dist/lib/testing/scenarios/governance.mjs +0 -6
  645. package/dist/lib/testing/scenarios/governance.mjs.map +1 -1
  646. package/dist/lib/testing/scenarios/health.mjs +0 -6
  647. package/dist/lib/testing/scenarios/health.mjs.map +1 -1
  648. package/dist/lib/testing/scenarios/index.mjs +0 -6
  649. package/dist/lib/testing/scenarios/index.mjs.map +1 -1
  650. package/dist/lib/testing/scenarios/media-buy.mjs +0 -6
  651. package/dist/lib/testing/scenarios/media-buy.mjs.map +1 -1
  652. package/dist/lib/testing/scenarios/schema-compliance.mjs +0 -6
  653. package/dist/lib/testing/scenarios/schema-compliance.mjs.map +1 -1
  654. package/dist/lib/testing/scenarios/signals.mjs +0 -6
  655. package/dist/lib/testing/scenarios/signals.mjs.map +1 -1
  656. package/dist/lib/testing/scenarios/sponsored-intelligence.mjs +0 -6
  657. package/dist/lib/testing/scenarios/sponsored-intelligence.mjs.map +1 -1
  658. package/dist/lib/testing/scenarios/trusted-match.mjs +0 -6
  659. package/dist/lib/testing/scenarios/trusted-match.mjs.map +1 -1
  660. package/dist/lib/testing/seed-merge.mjs +0 -6
  661. package/dist/lib/testing/seed-merge.mjs.map +1 -1
  662. package/dist/lib/testing/storyboard/agent-routing.mjs +0 -6
  663. package/dist/lib/testing/storyboard/agent-routing.mjs.map +1 -1
  664. package/dist/lib/testing/storyboard/assertions.mjs +0 -6
  665. package/dist/lib/testing/storyboard/assertions.mjs.map +1 -1
  666. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +0 -6
  667. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs.map +1 -1
  668. package/dist/lib/testing/storyboard/compliance.mjs +5 -6
  669. package/dist/lib/testing/storyboard/compliance.mjs.map +1 -1
  670. package/dist/lib/testing/storyboard/context.mjs +0 -6
  671. package/dist/lib/testing/storyboard/context.mjs.map +1 -1
  672. package/dist/lib/testing/storyboard/default-invariants.mjs +0 -6
  673. package/dist/lib/testing/storyboard/default-invariants.mjs.map +1 -1
  674. package/dist/lib/testing/storyboard/index.mjs +0 -6
  675. package/dist/lib/testing/storyboard/index.mjs.map +1 -1
  676. package/dist/lib/testing/storyboard/junit.mjs +0 -6
  677. package/dist/lib/testing/storyboard/junit.mjs.map +1 -1
  678. package/dist/lib/testing/storyboard/loader.mjs +0 -6
  679. package/dist/lib/testing/storyboard/loader.mjs.map +1 -1
  680. package/dist/lib/testing/storyboard/parallel-dispatch.mjs +0 -6
  681. package/dist/lib/testing/storyboard/parallel-dispatch.mjs.map +1 -1
  682. package/dist/lib/testing/storyboard/path.mjs +0 -6
  683. package/dist/lib/testing/storyboard/path.mjs.map +1 -1
  684. package/dist/lib/testing/storyboard/probes.mjs +0 -6
  685. package/dist/lib/testing/storyboard/probes.mjs.map +1 -1
  686. package/dist/lib/testing/storyboard/rate-limit-trip.mjs +0 -6
  687. package/dist/lib/testing/storyboard/rate-limit-trip.mjs.map +1 -1
  688. package/dist/lib/testing/storyboard/rejection-hints.mjs +0 -6
  689. package/dist/lib/testing/storyboard/rejection-hints.mjs.map +1 -1
  690. package/dist/lib/testing/storyboard/request-builder.mjs +0 -6
  691. package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
  692. package/dist/lib/testing/storyboard/request-signing/builder.mjs +0 -6
  693. package/dist/lib/testing/storyboard/request-signing/builder.mjs.map +1 -1
  694. package/dist/lib/testing/storyboard/request-signing/grader.mjs +0 -6
  695. package/dist/lib/testing/storyboard/request-signing/grader.mjs.map +1 -1
  696. package/dist/lib/testing/storyboard/request-signing/index.mjs +0 -6
  697. package/dist/lib/testing/storyboard/request-signing/index.mjs.map +1 -1
  698. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +0 -6
  699. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs.map +1 -1
  700. package/dist/lib/testing/storyboard/request-signing/probe.mjs +0 -6
  701. package/dist/lib/testing/storyboard/request-signing/probe.mjs.map +1 -1
  702. package/dist/lib/testing/storyboard/request-signing/synthesize.mjs +0 -6
  703. package/dist/lib/testing/storyboard/request-signing/synthesize.mjs.map +1 -1
  704. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs +0 -6
  705. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs.map +1 -1
  706. package/dist/lib/testing/storyboard/request-signing/types.mjs +0 -6
  707. package/dist/lib/testing/storyboard/request-signing/types.mjs.map +1 -1
  708. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +0 -6
  709. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
  710. package/dist/lib/testing/storyboard/runner.mjs +0 -6
  711. package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
  712. package/dist/lib/testing/storyboard/sandbox-entities.mjs +0 -6
  713. package/dist/lib/testing/storyboard/sandbox-entities.mjs.map +1 -1
  714. package/dist/lib/testing/storyboard/seeding.mjs +0 -6
  715. package/dist/lib/testing/storyboard/seeding.mjs.map +1 -1
  716. package/dist/lib/testing/storyboard/shape-drift-hints.mjs +0 -6
  717. package/dist/lib/testing/storyboard/shape-drift-hints.mjs.map +1 -1
  718. package/dist/lib/testing/storyboard/signer-grader/grader.mjs +0 -6
  719. package/dist/lib/testing/storyboard/signer-grader/grader.mjs.map +1 -1
  720. package/dist/lib/testing/storyboard/signer-grader/index.mjs +0 -6
  721. package/dist/lib/testing/storyboard/signer-grader/index.mjs.map +1 -1
  722. package/dist/lib/testing/storyboard/signer-grader/types.mjs +0 -6
  723. package/dist/lib/testing/storyboard/strict-validation-hints.mjs +0 -6
  724. package/dist/lib/testing/storyboard/strict-validation-hints.mjs.map +1 -1
  725. package/dist/lib/testing/storyboard/task-map.mjs +0 -6
  726. package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
  727. package/dist/lib/testing/storyboard/test-kit.mjs +0 -6
  728. package/dist/lib/testing/storyboard/test-kit.mjs.map +1 -1
  729. package/dist/lib/testing/storyboard/types.mjs +0 -6
  730. package/dist/lib/testing/storyboard/types.mjs.map +1 -1
  731. package/dist/lib/testing/storyboard/validations.mjs +0 -6
  732. package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
  733. package/dist/lib/testing/storyboard/webhook-assertions.mjs +0 -6
  734. package/dist/lib/testing/storyboard/webhook-assertions.mjs.map +1 -1
  735. package/dist/lib/testing/storyboard/webhook-receiver.mjs +0 -6
  736. package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
  737. package/dist/lib/testing/stubs/governance-agent-stub.mjs +0 -6
  738. package/dist/lib/testing/stubs/governance-agent-stub.mjs.map +1 -1
  739. package/dist/lib/testing/stubs/index.mjs +0 -6
  740. package/dist/lib/testing/stubs/index.mjs.map +1 -1
  741. package/dist/lib/testing/test-controller.mjs +0 -6
  742. package/dist/lib/testing/test-controller.mjs.map +1 -1
  743. package/dist/lib/testing/test-helpers.mjs +0 -6
  744. package/dist/lib/testing/test-helpers.mjs.map +1 -1
  745. package/dist/lib/testing/types.mjs +0 -6
  746. package/dist/lib/types/adcp.mjs +0 -6
  747. package/dist/lib/types/adcp.mjs.map +1 -1
  748. package/dist/lib/types/asset-instances.mjs +0 -6
  749. package/dist/lib/types/compat.mjs +0 -6
  750. package/dist/lib/types/compat.mjs.map +1 -1
  751. package/dist/lib/types/core.generated.mjs +0 -6
  752. package/dist/lib/types/enums.generated.mjs +0 -6
  753. package/dist/lib/types/enums.generated.mjs.map +1 -1
  754. package/dist/lib/types/error-codes.mjs +0 -6
  755. package/dist/lib/types/error-codes.mjs.map +1 -1
  756. package/dist/lib/types/error-details.aliases.mjs +0 -6
  757. package/dist/lib/types/error-details.aliases.mjs.map +1 -1
  758. package/dist/lib/types/format-asset-slots.mjs +0 -6
  759. package/dist/lib/types/forward-compat-error-codes.mjs +0 -6
  760. package/dist/lib/types/forward-compat-error-codes.mjs.map +1 -1
  761. package/dist/lib/types/index.mjs +0 -6
  762. package/dist/lib/types/index.mjs.map +1 -1
  763. package/dist/lib/types/inline-enums.aliases.mjs +0 -6
  764. package/dist/lib/types/inline-enums.aliases.mjs.map +1 -1
  765. package/dist/lib/types/inline-enums.generated.mjs +0 -6
  766. package/dist/lib/types/inline-enums.generated.mjs.map +1 -1
  767. package/dist/lib/types/manifest.generated.mjs +0 -6
  768. package/dist/lib/types/manifest.generated.mjs.map +1 -1
  769. package/dist/lib/types/schemas.generated.mjs +0 -6
  770. package/dist/lib/types/schemas.generated.mjs.map +1 -1
  771. package/dist/lib/types/server-payload-aliases.mjs +0 -6
  772. package/dist/lib/types/server-payload.mjs +0 -6
  773. package/dist/lib/types/sync-rows.mjs +0 -6
  774. package/dist/lib/types/tools.generated.mjs +0 -6
  775. package/dist/lib/types/v2-5/index.mjs +0 -6
  776. package/dist/lib/types/v2-5/index.mjs.map +1 -1
  777. package/dist/lib/types/v2-5/tools.generated.mjs +0 -6
  778. package/dist/lib/types/v3-1-beta/index.mjs +0 -6
  779. package/dist/lib/types/v3-1-beta/index.mjs.map +1 -1
  780. package/dist/lib/types/v3-1-beta/tools.generated.mjs +0 -6
  781. package/dist/lib/types/wellknown-schemas.generated.mjs +0 -6
  782. package/dist/lib/types/wellknown-schemas.generated.mjs.map +1 -1
  783. package/dist/lib/upstream-recorder/constants.mjs +0 -6
  784. package/dist/lib/upstream-recorder/constants.mjs.map +1 -1
  785. package/dist/lib/upstream-recorder/index.mjs +0 -6
  786. package/dist/lib/upstream-recorder/index.mjs.map +1 -1
  787. package/dist/lib/upstream-recorder/recorder.mjs +0 -6
  788. package/dist/lib/upstream-recorder/recorder.mjs.map +1 -1
  789. package/dist/lib/upstream-recorder/types.mjs +0 -6
  790. package/dist/lib/upstream-recorder/types.mjs.map +1 -1
  791. package/dist/lib/utils/a2a-artifacts.mjs +0 -6
  792. package/dist/lib/utils/a2a-artifacts.mjs.map +1 -1
  793. package/dist/lib/utils/a2a-discovery.mjs +0 -6
  794. package/dist/lib/utils/a2a-discovery.mjs.map +1 -1
  795. package/dist/lib/utils/activation-key-builders.mjs +0 -6
  796. package/dist/lib/utils/activation-key-builders.mjs.map +1 -1
  797. package/dist/lib/utils/adcp-version-config.mjs +0 -6
  798. package/dist/lib/utils/adcp-version-config.mjs.map +1 -1
  799. package/dist/lib/utils/asset-builders.mjs +0 -6
  800. package/dist/lib/utils/asset-builders.mjs.map +1 -1
  801. package/dist/lib/utils/build-creative-return-builders.mjs +0 -6
  802. package/dist/lib/utils/build-creative-return-builders.mjs.map +1 -1
  803. package/dist/lib/utils/buyer-retry-policy.mjs +0 -6
  804. package/dist/lib/utils/buyer-retry-policy.mjs.map +1 -1
  805. package/dist/lib/utils/capabilities.mjs +0 -6
  806. package/dist/lib/utils/capabilities.mjs.map +1 -1
  807. package/dist/lib/utils/capability-rollups.mjs +0 -6
  808. package/dist/lib/utils/capability-rollups.mjs.map +1 -1
  809. package/dist/lib/utils/creative-adapter.mjs +0 -6
  810. package/dist/lib/utils/creative-adapter.mjs.map +1 -1
  811. package/dist/lib/utils/creative-delivery.mjs +0 -6
  812. package/dist/lib/utils/creative-delivery.mjs.map +1 -1
  813. package/dist/lib/utils/deprecation.mjs +0 -6
  814. package/dist/lib/utils/deprecation.mjs.map +1 -1
  815. package/dist/lib/utils/envelope-status-compat.mjs +0 -6
  816. package/dist/lib/utils/envelope-status-compat.mjs.map +1 -1
  817. package/dist/lib/utils/error-extraction.mjs +0 -6
  818. package/dist/lib/utils/error-extraction.mjs.map +1 -1
  819. package/dist/lib/utils/extract-result.mjs +0 -6
  820. package/dist/lib/utils/extract-result.mjs.map +1 -1
  821. package/dist/lib/utils/format-asset-slot-builders.mjs +0 -6
  822. package/dist/lib/utils/format-asset-slot-builders.mjs.map +1 -1
  823. package/dist/lib/utils/format-assets.mjs +0 -6
  824. package/dist/lib/utils/format-assets.mjs.map +1 -1
  825. package/dist/lib/utils/format-render-builders.mjs +0 -6
  826. package/dist/lib/utils/format-render-builders.mjs.map +1 -1
  827. package/dist/lib/utils/format-renders.mjs +0 -6
  828. package/dist/lib/utils/format-renders.mjs.map +1 -1
  829. package/dist/lib/utils/get-products-cache-scope.mjs +0 -6
  830. package/dist/lib/utils/get-products-cache-scope.mjs.map +1 -1
  831. package/dist/lib/utils/glob.mjs +0 -6
  832. package/dist/lib/utils/glob.mjs.map +1 -1
  833. package/dist/lib/utils/global-async-local-storage.mjs +0 -6
  834. package/dist/lib/utils/global-async-local-storage.mjs.map +1 -1
  835. package/dist/lib/utils/idempotency.mjs +0 -6
  836. package/dist/lib/utils/idempotency.mjs.map +1 -1
  837. package/dist/lib/utils/index.mjs +0 -6
  838. package/dist/lib/utils/index.mjs.map +1 -1
  839. package/dist/lib/utils/jcs.mjs +0 -6
  840. package/dist/lib/utils/jcs.mjs.map +1 -1
  841. package/dist/lib/utils/json-depth.mjs +0 -6
  842. package/dist/lib/utils/json-depth.mjs.map +1 -1
  843. package/dist/lib/utils/logger.mjs +0 -6
  844. package/dist/lib/utils/logger.mjs.map +1 -1
  845. package/dist/lib/utils/media-buy-delivery-notification-builders.mjs +0 -6
  846. package/dist/lib/utils/media-buy-delivery-notification-builders.mjs.map +1 -1
  847. package/dist/lib/utils/media-buy-status.mjs +0 -6
  848. package/dist/lib/utils/media-buy-status.mjs.map +1 -1
  849. package/dist/lib/utils/pagination.mjs +0 -6
  850. package/dist/lib/utils/pagination.mjs.map +1 -1
  851. package/dist/lib/utils/preview-creative-builders.mjs +0 -6
  852. package/dist/lib/utils/preview-creative-builders.mjs.map +1 -1
  853. package/dist/lib/utils/preview-normalizer.mjs +0 -6
  854. package/dist/lib/utils/preview-normalizer.mjs.map +1 -1
  855. package/dist/lib/utils/preview-utils.mjs +0 -6
  856. package/dist/lib/utils/preview-utils.mjs.map +1 -1
  857. package/dist/lib/utils/pricing-adapter.mjs +0 -6
  858. package/dist/lib/utils/pricing-adapter.mjs.map +1 -1
  859. package/dist/lib/utils/probe-policy.mjs +0 -6
  860. package/dist/lib/utils/probe-policy.mjs.map +1 -1
  861. package/dist/lib/utils/protocol-detection.mjs +0 -6
  862. package/dist/lib/utils/protocol-detection.mjs.map +1 -1
  863. package/dist/lib/utils/redact-secrets.mjs +0 -6
  864. package/dist/lib/utils/redact-secrets.mjs.map +1 -1
  865. package/dist/lib/utils/redis-default-prefix-warn.mjs +0 -6
  866. package/dist/lib/utils/redis-default-prefix-warn.mjs.map +1 -1
  867. package/dist/lib/utils/render-builders.mjs +0 -6
  868. package/dist/lib/utils/render-builders.mjs.map +1 -1
  869. package/dist/lib/utils/request-normalizer.mjs +0 -6
  870. package/dist/lib/utils/request-normalizer.mjs.map +1 -1
  871. package/dist/lib/utils/response-schemas.mjs +0 -6
  872. package/dist/lib/utils/response-schemas.mjs.map +1 -1
  873. package/dist/lib/utils/response-unwrapper.mjs +0 -6
  874. package/dist/lib/utils/response-unwrapper.mjs.map +1 -1
  875. package/dist/lib/utils/retry.mjs +0 -6
  876. package/dist/lib/utils/retry.mjs.map +1 -1
  877. package/dist/lib/utils/signal-discovery-helpers.mjs +0 -6
  878. package/dist/lib/utils/signal-discovery-helpers.mjs.map +1 -1
  879. package/dist/lib/utils/signal-id-builders.mjs +0 -6
  880. package/dist/lib/utils/signal-id-builders.mjs.map +1 -1
  881. package/dist/lib/utils/sync-creatives-adapter.mjs +0 -6
  882. package/dist/lib/utils/sync-creatives-adapter.mjs.map +1 -1
  883. package/dist/lib/utils/task-state.mjs +0 -6
  884. package/dist/lib/utils/task-state.mjs.map +1 -1
  885. package/dist/lib/utils/tool-request-schemas.mjs +0 -6
  886. package/dist/lib/utils/tool-request-schemas.mjs.map +1 -1
  887. package/dist/lib/utils/typeGuards.mjs +0 -6
  888. package/dist/lib/utils/typeGuards.mjs.map +1 -1
  889. package/dist/lib/utils/union-errors.mjs +0 -6
  890. package/dist/lib/utils/union-errors.mjs.map +1 -1
  891. package/dist/lib/utils/validate-user-agent.mjs +0 -6
  892. package/dist/lib/utils/validate-user-agent.mjs.map +1 -1
  893. package/dist/lib/v2/format-schema/fetch.mjs +0 -6
  894. package/dist/lib/v2/format-schema/fetch.mjs.map +1 -1
  895. package/dist/lib/v2/format-schema/index.mjs +0 -6
  896. package/dist/lib/v2/format-schema/index.mjs.map +1 -1
  897. package/dist/lib/v2/format-schema/regex-safety.mjs +0 -6
  898. package/dist/lib/v2/format-schema/regex-safety.mjs.map +1 -1
  899. package/dist/lib/v2/format-schema/resolver.mjs +7 -8
  900. package/dist/lib/v2/format-schema/resolver.mjs.map +1 -1
  901. package/dist/lib/v2/format-schema/sandbox-refs.mjs +0 -6
  902. package/dist/lib/v2/format-schema/sandbox-refs.mjs.map +1 -1
  903. package/dist/lib/v2/projection/augment-response.mjs +0 -6
  904. package/dist/lib/v2/projection/augment-response.mjs.map +1 -1
  905. package/dist/lib/v2/projection/builders.mjs +0 -6
  906. package/dist/lib/v2/projection/builders.mjs.map +1 -1
  907. package/dist/lib/v2/projection/cache-versions.mjs +0 -6
  908. package/dist/lib/v2/projection/cache-versions.mjs.map +1 -1
  909. package/dist/lib/v2/projection/canonical-properties.mjs +5 -6
  910. package/dist/lib/v2/projection/canonical-properties.mjs.map +1 -1
  911. package/dist/lib/v2/projection/catalog.mjs +5 -6
  912. package/dist/lib/v2/projection/catalog.mjs.map +1 -1
  913. package/dist/lib/v2/projection/constants.mjs +0 -6
  914. package/dist/lib/v2/projection/constants.mjs.map +1 -1
  915. package/dist/lib/v2/projection/index.mjs +0 -6
  916. package/dist/lib/v2/projection/index.mjs.map +1 -1
  917. package/dist/lib/v2/projection/registry.mjs +5 -6
  918. package/dist/lib/v2/projection/registry.mjs.map +1 -1
  919. package/dist/lib/v2/projection/types.mjs +0 -6
  920. package/dist/lib/v2/projection/v1-to-v2.mjs +0 -6
  921. package/dist/lib/v2/projection/v1-to-v2.mjs.map +1 -1
  922. package/dist/lib/v2/projection/v2-to-v1.mjs +0 -6
  923. package/dist/lib/v2/projection/v2-to-v1.mjs.map +1 -1
  924. package/dist/lib/v2/projection/write-side.mjs +0 -6
  925. package/dist/lib/v2/projection/write-side.mjs.map +1 -1
  926. package/dist/lib/v2/publisher-catalog/formats.mjs +0 -6
  927. package/dist/lib/v2/publisher-catalog/formats.mjs.map +1 -1
  928. package/dist/lib/v2/publisher-catalog/index.mjs +0 -6
  929. package/dist/lib/v2/publisher-catalog/index.mjs.map +1 -1
  930. package/dist/lib/validation/client-hooks.mjs +0 -6
  931. package/dist/lib/validation/client-hooks.mjs.map +1 -1
  932. package/dist/lib/validation/hints.mjs +0 -6
  933. package/dist/lib/validation/hints.mjs.map +1 -1
  934. package/dist/lib/validation/index.mjs +0 -6
  935. package/dist/lib/validation/index.mjs.map +1 -1
  936. package/dist/lib/validation/schema-errors.mjs +0 -6
  937. package/dist/lib/validation/schema-errors.mjs.map +1 -1
  938. package/dist/lib/validation/schema-loader.mjs +5 -6
  939. package/dist/lib/validation/schema-loader.mjs.map +1 -1
  940. package/dist/lib/validation/schema-validator.mjs +0 -6
  941. package/dist/lib/validation/schema-validator.mjs.map +1 -1
  942. package/dist/lib/validation/sync-creatives.mjs +0 -6
  943. package/dist/lib/validation/sync-creatives.mjs.map +1 -1
  944. package/dist/lib/version.d.mts +3 -3
  945. package/dist/lib/version.d.ts +3 -3
  946. package/dist/lib/version.js +3 -3
  947. package/dist/lib/version.js.map +1 -1
  948. package/dist/lib/version.mjs +3 -9
  949. package/dist/lib/version.mjs.map +1 -1
  950. package/dist/lib/webhooks/index.mjs +0 -6
  951. package/dist/lib/webhooks/index.mjs.map +1 -1
  952. package/dist/lib/wholesale-feed-sync/index.mjs +0 -6
  953. package/dist/lib/wholesale-feed-sync/index.mjs.map +1 -1
  954. package/dist/lib/wholesale-feed-sync/sync.mjs +0 -6
  955. package/dist/lib/wholesale-feed-sync/sync.mjs.map +1 -1
  956. package/dist/lib/wholesale-feed-sync/types.mjs +0 -6
  957. package/dist/lib/wholesale-feed-sync/webhook-notification.mjs +0 -6
  958. package/dist/lib/wholesale-feed-sync/webhook-notification.mjs.map +1 -1
  959. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/brand-jwks.ts"],"sourcesContent":["/**\n * Receiver-side ergonomic: resolve a sender's JWKS by fetching their\n * `brand.json`, extracting the `jwks_uri` for the agent whose webhooks we're\n * verifying, and delegating to {@link HttpsJwksResolver}.\n *\n * Hand the resulting instance to `verifyWebhookSignature.jwks` (or\n * `verifyRequestSignature.jwks`) and the receiver never has to know where the\n * sender hosts their keys — brand.json is the single source of truth.\n *\n * Follows the two documented redirect variants of `brand.json`\n * (`authoritative_location` and `house`) up to a caller-configurable hop\n * depth. When the selected agent has no `jwks_uri`, falls back to\n * `/.well-known/jwks.json` on the origin of the agent's `url` — but only\n * when that origin matches the final brand.json origin. The spec's\n * well-known fallback exists so publishers hosting brand.json and their\n * agents on the same origin can skip the explicit `jwks_uri`; accepting a\n * cross-origin fallback would let an attacker pivot the trust anchor to a\n * controlled host with a permissive JWKS.\n *\n * Caching is stacked with the inner {@link HttpsJwksResolver}: brand.json\n * honors its own `Cache-Control`/`ETag` (bounded by `maxAgeSeconds`), and\n * unknown-kid refreshes cascade — first to the JWKS endpoint, then (if the\n * JWKS still doesn't have the kid and the brand.json cooldown has elapsed) to\n * brand.json itself, in case the sender rotated `jwks_uri`.\n */\nimport { ssrfSafeFetch } from '../net';\nimport type { JwksResolver } from './jwks';\nimport { HttpsJwksResolver, type HttpsJwksResolverOptions } from './jwks-https';\nimport type { AdcpJsonWebKey } from './types';\n\nexport type BrandAgentType =\n | 'brand'\n | 'rights'\n | 'measurement'\n | 'governance'\n | 'creative'\n | 'sales'\n | 'buying'\n | 'signals';\n\nexport type BrandJsonResolverErrorCode =\n | 'invalid_url'\n | 'invalid_house'\n | 'redirect_loop'\n | 'redirect_depth_exceeded'\n | 'fetch_failed'\n | 'invalid_body'\n | 'schema_invalid'\n | 'agent_not_found'\n | 'agent_ambiguous'\n | 'jwks_origin_mismatch';\n\n/**\n * Typed error surfaced by the resolver pipeline. Verifier callers can fold\n * these into `webhook_signature_key_unknown` (or treat ambiguous/schema\n * errors as config bugs) without parsing error message strings.\n */\nexport class BrandJsonResolverError extends Error {\n readonly code: BrandJsonResolverErrorCode;\n constructor(code: BrandJsonResolverErrorCode, message: string) {\n super(message);\n this.name = 'BrandJsonResolverError';\n this.code = code;\n }\n}\n\nexport interface BrandJsonJwksResolverOptions {\n /** Functional role of the agent whose keys we want to resolve. */\n agentType: BrandAgentType;\n /**\n * Agent id from `agents[].id`. Required when brand.json declares more than\n * one agent of the requested type (otherwise the selector is ambiguous).\n * Optional when the type is unique.\n */\n agentId?: string;\n /**\n * Brand id within a house portfolio (`brands[].id`). When omitted on a\n * portfolio brand.json, the resolver looks at `house.agents[]`. When set,\n * the resolver looks at `brands[brandId].agents[]` first and falls back to\n * `house.agents[]` if no agent of the requested type is declared on the\n * brand itself.\n */\n brandId?: string;\n /**\n * Minimum seconds between brand.json refetches. Mirrors the JWKS cooldown\n * and protects counterparties from being hammered by unknown-kid refreshes.\n * Default 30s (AdCP JWKS floor).\n */\n minCooldownSeconds?: number;\n /**\n * Absolute cap on how long a cached brand.json snapshot may be used before\n * a refetch is attempted, even if the counterparty's Cache-Control would\n * allow longer. Default 3600s (1 hour).\n */\n maxAgeSeconds?: number;\n /**\n * Maximum redirect hops to follow through `authoritative_location` /\n * `house` variants. Default 3 — enough for `authoritative_location → house\n * → portfolio` without inviting loops.\n */\n maxRedirects?: number;\n /**\n * Allow `http://` / private-IP brand.json and JWKS URLs (dev loops only).\n * Default false. Forwarded to both the brand.json fetch and the inner\n * HttpsJwksResolver so a single flag unlocks the whole chain.\n */\n allowPrivateIp?: boolean;\n /**\n * Forwarded to the inner {@link HttpsJwksResolver} constructor.\n * `allowPrivateIp` and `now` are set from the outer options and should not\n * be passed here.\n */\n jwksOptions?: Omit<HttpsJwksResolverOptions, 'allowPrivateIp' | 'now'>;\n /** Clock override for deterministic tests. Returns epoch seconds. */\n now?: () => number;\n}\n\ninterface BrandSnapshot {\n /** The JWKS URL we resolved from the brand.json agent entry. */\n jwksUri: string;\n /** The agent's `url` — stable result attribution for verified webhooks. */\n agentUrl: string;\n etag?: string;\n fetchedAt: number;\n expiresAt: number;\n}\n\ninterface SelectedAgent {\n url: string;\n jwksUri: string;\n}\n\nconst DEFAULT_MIN_COOLDOWN_SECONDS = 30;\nconst DEFAULT_MAX_AGE_SECONDS = 3600;\nconst DEFAULT_MAX_REDIRECTS = 3;\n\n// Bare hostname pattern: lowercase labels separated by dots, no userinfo,\n// no path, no control characters. Matches the `house` domain regex used in\n// the brand.json schema (`^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]…)*$`).\nconst BARE_HOSTNAME = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/;\n\n/**\n * JWKS resolver backed by a sender's `brand.json`. Construct one per\n * counterparty (or keyed by `brand.json` URL + agent selector) and hand it to\n * the webhook/request verifier as the `jwks` dependency.\n */\nexport class BrandJsonJwksResolver implements JwksResolver {\n private readonly url: string;\n private readonly selector: {\n agentType: BrandAgentType;\n agentId?: string;\n brandId?: string;\n };\n private readonly minCooldown: number;\n private readonly maxAge: number;\n private readonly maxRedirects: number;\n private readonly allowPrivateIp: boolean;\n private readonly jwksOptions: Omit<HttpsJwksResolverOptions, 'allowPrivateIp' | 'now'>;\n private readonly now: () => number;\n private snapshot: BrandSnapshot | undefined;\n private inner: HttpsJwksResolver | undefined;\n private inFlight: Promise<void> | undefined;\n\n constructor(brandJsonUrl: string, options: BrandJsonJwksResolverOptions) {\n this.url = brandJsonUrl;\n this.selector = {\n agentType: options.agentType,\n ...(options.agentId !== undefined && { agentId: options.agentId }),\n ...(options.brandId !== undefined && { brandId: options.brandId }),\n };\n this.minCooldown = options.minCooldownSeconds ?? DEFAULT_MIN_COOLDOWN_SECONDS;\n this.maxAge = options.maxAgeSeconds ?? DEFAULT_MAX_AGE_SECONDS;\n this.maxRedirects = options.maxRedirects ?? DEFAULT_MAX_REDIRECTS;\n this.allowPrivateIp = options.allowPrivateIp ?? false;\n this.jwksOptions = options.jwksOptions ?? {};\n this.now = options.now ?? (() => Math.floor(Date.now() / 1000));\n }\n\n /**\n * Resolve a JWK by `kid`. On a cold cache, fetches brand.json first; on an\n * expired brand.json snapshot, refreshes respecting the cooldown. Unknown\n * kids cascade: first ask the inner HttpsJwksResolver (which will refetch\n * its own URL if cooldown has elapsed); if still unknown, refresh\n * brand.json in case `jwks_uri` rotated.\n */\n async resolve(keyid: string): Promise<AdcpJsonWebKey | null> {\n if (!this.snapshot || !this.inner) {\n await this.refresh();\n } else if (this.now() > this.snapshot.expiresAt && this.now() - this.snapshot.fetchedAt >= this.minCooldown) {\n await this.refresh().catch(() => {\n /* keep stale on transient failure */\n });\n }\n if (!this.inner) return null;\n\n const hit = await this.inner.resolve(keyid);\n if (hit) return hit;\n\n if (this.snapshot && this.now() - this.snapshot.fetchedAt >= this.minCooldown) {\n await this.refresh().catch(() => {\n /* keep stale on transient failure */\n });\n return this.inner ? this.inner.resolve(keyid) : null;\n }\n return null;\n }\n\n /**\n * The agent URL we resolved `jwks_uri` from. Populated after the first\n * successful refresh; useful for verifier result attribution\n * (`VerifyWebhookOptions.agentUrlForKeyid`).\n */\n get agentUrl(): string | undefined {\n return this.snapshot?.agentUrl;\n }\n\n /** Force a refetch of both brand.json and the inner JWKS, bypassing the cooldown. */\n async forceRefresh(): Promise<void> {\n this.snapshot = undefined;\n this.inner = undefined;\n await this.refresh();\n }\n\n private async refresh(): Promise<void> {\n if (this.inFlight) {\n await this.inFlight;\n return;\n }\n this.inFlight = this.doRefresh().finally(() => {\n this.inFlight = undefined;\n });\n await this.inFlight;\n }\n\n private async doRefresh(): Promise<void> {\n const fetched = await fetchBrandJson({\n startUrl: this.url,\n currentEtag: this.snapshot?.etag,\n maxRedirects: this.maxRedirects,\n allowPrivateIp: this.allowPrivateIp,\n });\n\n // 304 on the entry URL: extend the lifetime, keep the inner resolver.\n if (fetched.status === 'not_modified' && this.snapshot) {\n this.snapshot = {\n ...this.snapshot,\n ...(fetched.etag && { etag: fetched.etag }),\n fetchedAt: this.now(),\n expiresAt: this.now() + computeLifetime(fetched.cacheControl, this.maxAge),\n };\n return;\n }\n\n const agent = selectAgent(fetched.data, fetched.finalUrl, this.selector);\n\n if (!this.inner || this.snapshot?.jwksUri !== agent.jwksUri) {\n this.inner = new HttpsJwksResolver(agent.jwksUri, {\n ...this.jwksOptions,\n allowPrivateIp: this.allowPrivateIp,\n now: this.now,\n });\n }\n this.snapshot = {\n jwksUri: agent.jwksUri,\n agentUrl: agent.url,\n ...(fetched.etag && { etag: fetched.etag }),\n fetchedAt: this.now(),\n expiresAt: this.now() + computeLifetime(fetched.cacheControl, this.maxAge),\n };\n }\n}\n\ninterface FetchedBrandJson {\n status: 'ok' | 'not_modified';\n finalUrl: string;\n data: unknown;\n etag?: string;\n cacheControl?: string;\n}\n\n/**\n * Fetch brand.json from `startUrl`, following `authoritative_location` and\n * `house` string redirect variants up to `maxRedirects` hops. Each hop goes\n * through the SSRF-safe fetch primitive so an attacker-supplied chain can't\n * land on a private address or IMDS. Redirect targets are structurally\n * validated before dispatch — an attacker-controlled brand.json that emits\n * `{\"house\": \"evil.com\\\\@victim.com\"}` or `{\"authoritative_location\":\n * \"http://169.254.169.254/...\"}` is rejected at parse time rather than\n * relying on `ssrfSafeFetch` to catch every pathological shape.\n */\nasync function fetchBrandJson(args: {\n startUrl: string;\n currentEtag?: string;\n maxRedirects: number;\n allowPrivateIp: boolean;\n}): Promise<FetchedBrandJson> {\n const seen = new Set<string>();\n let url = canonicalizeUrl(args.startUrl, args.allowPrivateIp);\n\n for (let hop = 0; hop <= args.maxRedirects; hop++) {\n if (seen.has(url)) {\n throw new BrandJsonResolverError('redirect_loop', `brand.json redirect loop detected`);\n }\n seen.add(url);\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n };\n // Only attach If-None-Match on the entry URL: a 304 short-circuits the\n // whole chain, so revalidating a deeper hop with a stale ETag would be\n // a lie about the redirect target.\n if (hop === 0 && args.currentEtag) headers['if-none-match'] = args.currentEtag;\n\n const res = await ssrfSafeFetch(url, {\n method: 'GET',\n headers,\n allowPrivateIp: args.allowPrivateIp,\n });\n\n if (hop === 0 && res.status === 304) {\n return {\n status: 'not_modified',\n finalUrl: url,\n data: null,\n ...(res.headers['etag'] && { etag: res.headers['etag'] }),\n ...(res.headers['cache-control'] && { cacheControl: res.headers['cache-control'] }),\n };\n }\n if (res.status !== 200) {\n throw new BrandJsonResolverError('fetch_failed', `brand.json fetch returned HTTP ${res.status}`);\n }\n\n const text = Buffer.from(res.body).toString('utf8');\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new BrandJsonResolverError('invalid_body', `brand.json response is not valid JSON`);\n }\n if (!parsed || typeof parsed !== 'object') {\n throw new BrandJsonResolverError('invalid_body', `brand.json response is not an object`);\n }\n\n const obj = parsed as Record<string, unknown>;\n const authoritative = typeof obj.authoritative_location === 'string' ? obj.authoritative_location : undefined;\n const house = typeof obj.house === 'string' ? obj.house : undefined;\n\n if (authoritative !== undefined) {\n if (hop === args.maxRedirects) {\n throw new BrandJsonResolverError('redirect_depth_exceeded', `brand.json redirect depth exceeded`);\n }\n url = canonicalizeUrl(authoritative, args.allowPrivateIp);\n continue;\n }\n if (house !== undefined) {\n // The \"house string\" redirect variant: a bare domain pointing at the\n // authoritative portfolio. Reject anything that isn't a bare hostname\n // so an attacker can't inject userinfo, paths, or ports via the\n // interpolation.\n if (!BARE_HOSTNAME.test(house)) {\n throw new BrandJsonResolverError('invalid_house', `brand.json \"house\" is not a bare hostname`);\n }\n if (hop === args.maxRedirects) {\n throw new BrandJsonResolverError('redirect_depth_exceeded', `brand.json redirect depth exceeded`);\n }\n url = canonicalizeUrl(`https://${house}/.well-known/brand.json`, args.allowPrivateIp);\n continue;\n }\n\n // Narrow shape validation on the terminal document. Full BrandJsonSchema\n // validation is stricter than we need (it enforces `^https://` on URLs,\n // which ssrfSafeFetch already polices) and fails too readily on trailing\n // portfolio fields the resolver doesn't touch. What we MUST reject: a\n // document whose shape would let an attacker smuggle a non-string url or\n // jwks_uri past the selector.\n assertBrandJsonShape(obj);\n\n return {\n status: 'ok',\n finalUrl: url,\n data: obj,\n ...(res.headers['etag'] && { etag: res.headers['etag'] }),\n ...(res.headers['cache-control'] && { cacheControl: res.headers['cache-control'] }),\n };\n }\n\n throw new BrandJsonResolverError('redirect_depth_exceeded', `brand.json redirect depth exceeded`);\n}\n\n/**\n * Structurally validate a URL and return it in a canonical form for the\n * loop-detection `Set`. Rejects URLs that `ssrfSafeFetch` would later refuse\n * anyway — but catching them here gives a clearer error code and prevents\n * a malformed `authoritative_location` from silently bypassing the hop cap\n * because its string form differed from a prior seen URL.\n */\nfunction canonicalizeUrl(raw: string, allowPrivateIp: boolean): string {\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new BrandJsonResolverError('invalid_url', `brand.json URL is malformed`);\n }\n if (parsed.username || parsed.password) {\n throw new BrandJsonResolverError('invalid_url', `brand.json URL must not include userinfo`);\n }\n if (parsed.protocol !== 'https:' && !(allowPrivateIp && parsed.protocol === 'http:')) {\n throw new BrandJsonResolverError('invalid_url', `brand.json URL must use https://`);\n }\n // Fragments are not sent on the wire and must not smuggle loop-detection\n // aliases — strip them before stashing in `seen`.\n parsed.hash = '';\n return parsed.toString();\n}\n\nfunction isPortfolioHouse(value: unknown): boolean {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Walk every `agents[]` array we might consult and reject entries where\n * `url` or `jwks_uri` are present but non-string. A permissive walk here\n * catches a malformed document that `pickAgent` would otherwise silently\n * skip (a non-string url gets filtered out, so an attacker who declares\n * two agents of a type — one well-formed and one with a poisoned shape —\n * couldn't change the selector outcome, but schema-invalid payloads are\n * still a strong signal of compromise).\n */\nfunction assertBrandJsonShape(obj: Record<string, unknown>): void {\n const queues: unknown[] = [obj.agents];\n if (isPortfolioHouse(obj.house)) {\n const house = obj.house as Record<string, unknown>;\n queues.push(house.agents);\n if (Array.isArray(obj.brands)) {\n for (const brand of obj.brands as Record<string, unknown>[]) {\n if (brand) queues.push(brand.agents);\n }\n }\n }\n for (const q of queues) {\n if (q === undefined) continue;\n if (!Array.isArray(q)) {\n throw new BrandJsonResolverError('schema_invalid', 'brand.json `agents` must be an array');\n }\n for (const entry of q) {\n if (entry && typeof entry === 'object') {\n const e = entry as AgentEntry;\n if (e.url !== undefined && typeof e.url !== 'string') {\n throw new BrandJsonResolverError('schema_invalid', 'brand.json agent.url must be a string');\n }\n if (e.jwks_uri !== undefined && typeof e.jwks_uri !== 'string') {\n throw new BrandJsonResolverError('schema_invalid', 'brand.json agent.jwks_uri must be a string');\n }\n }\n }\n }\n}\n\n/** An agent entry as declared in brand.json `agents[]`. */\ninterface AgentEntry {\n type?: string;\n url?: string;\n id?: string;\n jwks_uri?: string;\n}\n\nfunction selectAgent(\n data: unknown,\n finalBrandUrl: string,\n selector: { agentType: BrandAgentType; agentId?: string; brandId?: string }\n): SelectedAgent {\n if (!data || typeof data !== 'object') {\n throw new BrandJsonResolverError(\n 'agent_not_found',\n `brand.json has no agent matching ${describeSelector(selector)}`\n );\n }\n const obj = data as Record<string, unknown>;\n\n let picked: SelectedAgent | undefined;\n if (isPortfolioHouse(obj.house)) {\n const house = obj.house as Record<string, unknown>;\n if (selector.brandId !== undefined) {\n const brands = Array.isArray(obj.brands) ? (obj.brands as Record<string, unknown>[]) : [];\n const brand = brands.find(b => b && b.id === selector.brandId);\n if (brand) picked = pickAgent(brand.agents, finalBrandUrl, selector);\n }\n picked ??= pickAgent(house.agents, finalBrandUrl, selector);\n } else {\n picked = pickAgent(obj.agents, finalBrandUrl, selector);\n }\n\n if (!picked) {\n throw new BrandJsonResolverError(\n 'agent_not_found',\n `brand.json has no agent matching ${describeSelector(selector)}`\n );\n }\n return picked;\n}\n\nfunction pickAgent(\n agents: unknown,\n finalBrandUrl: string,\n selector: { agentType: BrandAgentType; agentId?: string }\n): SelectedAgent | undefined {\n if (!Array.isArray(agents)) return undefined;\n const matches = agents.filter((a): a is AgentEntry => {\n if (!a || typeof a !== 'object') return false;\n const e = a as AgentEntry;\n if (e.type !== selector.agentType) return false;\n if (selector.agentId !== undefined && e.id !== selector.agentId) return false;\n return typeof e.url === 'string';\n });\n if (matches.length === 0) return undefined;\n if (matches.length > 1 && selector.agentId === undefined) {\n throw new BrandJsonResolverError(\n 'agent_ambiguous',\n `brand.json declares ${matches.length} agents of type \"${selector.agentType}\"; ` +\n `pass \\`agentId\\` to disambiguate (choices: ${matches.map(m => m.id ?? '<no-id>').join(', ')})`\n );\n }\n const agent = matches[0]!;\n const url = agent.url!;\n const jwksUri = agent.jwks_uri ?? defaultJwksUri(url, finalBrandUrl);\n return { url, jwksUri };\n}\n\n/**\n * Spec fallback: \"When absent, verifiers MUST default to /.well-known/jwks.json\n * on the origin of `url`.\" We strip any path/query/fragment from the agent\n * URL and replace it with the well-known path.\n *\n * Security: require the agent origin to match the final brand.json origin.\n * Without this check, an attacker-controlled brand.json could set\n * `agent.url: \"https://victim-internal.example/\"` and force the verifier to\n * treat that origin's JWKS as authoritative — a cross-origin trust pivot.\n * Publishers that genuinely host their agent on a different origin from\n * their brand.json MUST declare an explicit `jwks_uri` (and that URI is\n * validated at fetch time by the inner HttpsJwksResolver, not here).\n */\nfunction defaultJwksUri(agentUrl: string, finalBrandUrl: string): string {\n let agent: URL;\n try {\n agent = new URL(agentUrl);\n } catch {\n throw new BrandJsonResolverError('invalid_url', `agent.url is not a valid URL`);\n }\n const brand = new URL(finalBrandUrl);\n if (agent.origin !== brand.origin) {\n throw new BrandJsonResolverError(\n 'jwks_origin_mismatch',\n `agent.url origin (${agent.origin}) does not match brand.json origin (${brand.origin}); ` +\n `publisher must declare an explicit jwks_uri for cross-origin agents`\n );\n }\n return `${agent.origin}/.well-known/jwks.json`;\n}\n\nfunction describeSelector(selector: { agentType: BrandAgentType; agentId?: string; brandId?: string }): string {\n const parts = [`type=${selector.agentType}`];\n if (selector.agentId !== undefined) parts.push(`id=${selector.agentId}`);\n if (selector.brandId !== undefined) parts.push(`brand=${selector.brandId}`);\n return parts.join(' ');\n}\n\nfunction computeLifetime(cacheControl: string | undefined, maxAge: number): number {\n if (!cacheControl) return maxAge;\n const lower = cacheControl.toLowerCase();\n if (/\\bno-store\\b|\\bno-cache\\b/.test(lower)) return 0;\n const match = /max-age\\s*=\\s*(\\d+)/.exec(lower);\n if (match) {\n const serverMax = Number(match[1]);\n if (Number.isFinite(serverMax)) return Math.min(serverMax, maxAge);\n }\n return maxAge;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/brand-jwks.ts"],"sourcesContent":["/**\n * Receiver-side ergonomic: resolve a sender's JWKS by fetching their\n * `brand.json`, extracting the `jwks_uri` for the agent whose webhooks we're\n * verifying, and delegating to {@link HttpsJwksResolver}.\n *\n * Hand the resulting instance to `verifyWebhookSignature.jwks` (or\n * `verifyRequestSignature.jwks`) and the receiver never has to know where the\n * sender hosts their keys — brand.json is the single source of truth.\n *\n * Follows the two documented redirect variants of `brand.json`\n * (`authoritative_location` and `house`) up to a caller-configurable hop\n * depth. When the selected agent has no `jwks_uri`, falls back to\n * `/.well-known/jwks.json` on the origin of the agent's `url` — but only\n * when that origin matches the final brand.json origin. The spec's\n * well-known fallback exists so publishers hosting brand.json and their\n * agents on the same origin can skip the explicit `jwks_uri`; accepting a\n * cross-origin fallback would let an attacker pivot the trust anchor to a\n * controlled host with a permissive JWKS.\n *\n * Caching is stacked with the inner {@link HttpsJwksResolver}: brand.json\n * honors its own `Cache-Control`/`ETag` (bounded by `maxAgeSeconds`), and\n * unknown-kid refreshes cascade — first to the JWKS endpoint, then (if the\n * JWKS still doesn't have the kid and the brand.json cooldown has elapsed) to\n * brand.json itself, in case the sender rotated `jwks_uri`.\n */\nimport { ssrfSafeFetch } from '../net';\nimport type { JwksResolver } from './jwks';\nimport { HttpsJwksResolver, type HttpsJwksResolverOptions } from './jwks-https';\nimport type { AdcpJsonWebKey } from './types';\n\nexport type BrandAgentType =\n | 'brand'\n | 'rights'\n | 'measurement'\n | 'governance'\n | 'creative'\n | 'sales'\n | 'buying'\n | 'signals';\n\nexport type BrandJsonResolverErrorCode =\n | 'invalid_url'\n | 'invalid_house'\n | 'redirect_loop'\n | 'redirect_depth_exceeded'\n | 'fetch_failed'\n | 'invalid_body'\n | 'schema_invalid'\n | 'agent_not_found'\n | 'agent_ambiguous'\n | 'jwks_origin_mismatch';\n\n/**\n * Typed error surfaced by the resolver pipeline. Verifier callers can fold\n * these into `webhook_signature_key_unknown` (or treat ambiguous/schema\n * errors as config bugs) without parsing error message strings.\n */\nexport class BrandJsonResolverError extends Error {\n readonly code: BrandJsonResolverErrorCode;\n constructor(code: BrandJsonResolverErrorCode, message: string) {\n super(message);\n this.name = 'BrandJsonResolverError';\n this.code = code;\n }\n}\n\nexport interface BrandJsonJwksResolverOptions {\n /** Functional role of the agent whose keys we want to resolve. */\n agentType: BrandAgentType;\n /**\n * Agent id from `agents[].id`. Required when brand.json declares more than\n * one agent of the requested type (otherwise the selector is ambiguous).\n * Optional when the type is unique.\n */\n agentId?: string;\n /**\n * Brand id within a house portfolio (`brands[].id`). When omitted on a\n * portfolio brand.json, the resolver looks at `house.agents[]`. When set,\n * the resolver looks at `brands[brandId].agents[]` first and falls back to\n * `house.agents[]` if no agent of the requested type is declared on the\n * brand itself.\n */\n brandId?: string;\n /**\n * Minimum seconds between brand.json refetches. Mirrors the JWKS cooldown\n * and protects counterparties from being hammered by unknown-kid refreshes.\n * Default 30s (AdCP JWKS floor).\n */\n minCooldownSeconds?: number;\n /**\n * Absolute cap on how long a cached brand.json snapshot may be used before\n * a refetch is attempted, even if the counterparty's Cache-Control would\n * allow longer. Default 3600s (1 hour).\n */\n maxAgeSeconds?: number;\n /**\n * Maximum redirect hops to follow through `authoritative_location` /\n * `house` variants. Default 3 — enough for `authoritative_location → house\n * → portfolio` without inviting loops.\n */\n maxRedirects?: number;\n /**\n * Allow `http://` / private-IP brand.json and JWKS URLs (dev loops only).\n * Default false. Forwarded to both the brand.json fetch and the inner\n * HttpsJwksResolver so a single flag unlocks the whole chain.\n */\n allowPrivateIp?: boolean;\n /**\n * Forwarded to the inner {@link HttpsJwksResolver} constructor.\n * `allowPrivateIp` and `now` are set from the outer options and should not\n * be passed here.\n */\n jwksOptions?: Omit<HttpsJwksResolverOptions, 'allowPrivateIp' | 'now'>;\n /** Clock override for deterministic tests. Returns epoch seconds. */\n now?: () => number;\n}\n\ninterface BrandSnapshot {\n /** The JWKS URL we resolved from the brand.json agent entry. */\n jwksUri: string;\n /** The agent's `url` — stable result attribution for verified webhooks. */\n agentUrl: string;\n etag?: string;\n fetchedAt: number;\n expiresAt: number;\n}\n\ninterface SelectedAgent {\n url: string;\n jwksUri: string;\n}\n\nconst DEFAULT_MIN_COOLDOWN_SECONDS = 30;\nconst DEFAULT_MAX_AGE_SECONDS = 3600;\nconst DEFAULT_MAX_REDIRECTS = 3;\n\n// Bare hostname pattern: lowercase labels separated by dots, no userinfo,\n// no path, no control characters. Matches the `house` domain regex used in\n// the brand.json schema (`^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]…)*$`).\nconst BARE_HOSTNAME = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/;\n\n/**\n * JWKS resolver backed by a sender's `brand.json`. Construct one per\n * counterparty (or keyed by `brand.json` URL + agent selector) and hand it to\n * the webhook/request verifier as the `jwks` dependency.\n */\nexport class BrandJsonJwksResolver implements JwksResolver {\n private readonly url: string;\n private readonly selector: {\n agentType: BrandAgentType;\n agentId?: string;\n brandId?: string;\n };\n private readonly minCooldown: number;\n private readonly maxAge: number;\n private readonly maxRedirects: number;\n private readonly allowPrivateIp: boolean;\n private readonly jwksOptions: Omit<HttpsJwksResolverOptions, 'allowPrivateIp' | 'now'>;\n private readonly now: () => number;\n private snapshot: BrandSnapshot | undefined;\n private inner: HttpsJwksResolver | undefined;\n private inFlight: Promise<void> | undefined;\n\n constructor(brandJsonUrl: string, options: BrandJsonJwksResolverOptions) {\n this.url = brandJsonUrl;\n this.selector = {\n agentType: options.agentType,\n ...(options.agentId !== undefined && { agentId: options.agentId }),\n ...(options.brandId !== undefined && { brandId: options.brandId }),\n };\n this.minCooldown = options.minCooldownSeconds ?? DEFAULT_MIN_COOLDOWN_SECONDS;\n this.maxAge = options.maxAgeSeconds ?? DEFAULT_MAX_AGE_SECONDS;\n this.maxRedirects = options.maxRedirects ?? DEFAULT_MAX_REDIRECTS;\n this.allowPrivateIp = options.allowPrivateIp ?? false;\n this.jwksOptions = options.jwksOptions ?? {};\n this.now = options.now ?? (() => Math.floor(Date.now() / 1000));\n }\n\n /**\n * Resolve a JWK by `kid`. On a cold cache, fetches brand.json first; on an\n * expired brand.json snapshot, refreshes respecting the cooldown. Unknown\n * kids cascade: first ask the inner HttpsJwksResolver (which will refetch\n * its own URL if cooldown has elapsed); if still unknown, refresh\n * brand.json in case `jwks_uri` rotated.\n */\n async resolve(keyid: string): Promise<AdcpJsonWebKey | null> {\n if (!this.snapshot || !this.inner) {\n await this.refresh();\n } else if (this.now() > this.snapshot.expiresAt && this.now() - this.snapshot.fetchedAt >= this.minCooldown) {\n await this.refresh().catch(() => {\n /* keep stale on transient failure */\n });\n }\n if (!this.inner) return null;\n\n const hit = await this.inner.resolve(keyid);\n if (hit) return hit;\n\n if (this.snapshot && this.now() - this.snapshot.fetchedAt >= this.minCooldown) {\n await this.refresh().catch(() => {\n /* keep stale on transient failure */\n });\n return this.inner ? this.inner.resolve(keyid) : null;\n }\n return null;\n }\n\n /**\n * The agent URL we resolved `jwks_uri` from. Populated after the first\n * successful refresh; useful for verifier result attribution\n * (`VerifyWebhookOptions.agentUrlForKeyid`).\n */\n get agentUrl(): string | undefined {\n return this.snapshot?.agentUrl;\n }\n\n /** Force a refetch of both brand.json and the inner JWKS, bypassing the cooldown. */\n async forceRefresh(): Promise<void> {\n this.snapshot = undefined;\n this.inner = undefined;\n await this.refresh();\n }\n\n private async refresh(): Promise<void> {\n if (this.inFlight) {\n await this.inFlight;\n return;\n }\n this.inFlight = this.doRefresh().finally(() => {\n this.inFlight = undefined;\n });\n await this.inFlight;\n }\n\n private async doRefresh(): Promise<void> {\n const fetched = await fetchBrandJson({\n startUrl: this.url,\n currentEtag: this.snapshot?.etag,\n maxRedirects: this.maxRedirects,\n allowPrivateIp: this.allowPrivateIp,\n });\n\n // 304 on the entry URL: extend the lifetime, keep the inner resolver.\n if (fetched.status === 'not_modified' && this.snapshot) {\n this.snapshot = {\n ...this.snapshot,\n ...(fetched.etag && { etag: fetched.etag }),\n fetchedAt: this.now(),\n expiresAt: this.now() + computeLifetime(fetched.cacheControl, this.maxAge),\n };\n return;\n }\n\n const agent = selectAgent(fetched.data, fetched.finalUrl, this.selector);\n\n if (!this.inner || this.snapshot?.jwksUri !== agent.jwksUri) {\n this.inner = new HttpsJwksResolver(agent.jwksUri, {\n ...this.jwksOptions,\n allowPrivateIp: this.allowPrivateIp,\n now: this.now,\n });\n }\n this.snapshot = {\n jwksUri: agent.jwksUri,\n agentUrl: agent.url,\n ...(fetched.etag && { etag: fetched.etag }),\n fetchedAt: this.now(),\n expiresAt: this.now() + computeLifetime(fetched.cacheControl, this.maxAge),\n };\n }\n}\n\ninterface FetchedBrandJson {\n status: 'ok' | 'not_modified';\n finalUrl: string;\n data: unknown;\n etag?: string;\n cacheControl?: string;\n}\n\n/**\n * Fetch brand.json from `startUrl`, following `authoritative_location` and\n * `house` string redirect variants up to `maxRedirects` hops. Each hop goes\n * through the SSRF-safe fetch primitive so an attacker-supplied chain can't\n * land on a private address or IMDS. Redirect targets are structurally\n * validated before dispatch — an attacker-controlled brand.json that emits\n * `{\"house\": \"evil.com\\\\@victim.com\"}` or `{\"authoritative_location\":\n * \"http://169.254.169.254/...\"}` is rejected at parse time rather than\n * relying on `ssrfSafeFetch` to catch every pathological shape.\n */\nasync function fetchBrandJson(args: {\n startUrl: string;\n currentEtag?: string;\n maxRedirects: number;\n allowPrivateIp: boolean;\n}): Promise<FetchedBrandJson> {\n const seen = new Set<string>();\n let url = canonicalizeUrl(args.startUrl, args.allowPrivateIp);\n\n for (let hop = 0; hop <= args.maxRedirects; hop++) {\n if (seen.has(url)) {\n throw new BrandJsonResolverError('redirect_loop', `brand.json redirect loop detected`);\n }\n seen.add(url);\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n };\n // Only attach If-None-Match on the entry URL: a 304 short-circuits the\n // whole chain, so revalidating a deeper hop with a stale ETag would be\n // a lie about the redirect target.\n if (hop === 0 && args.currentEtag) headers['if-none-match'] = args.currentEtag;\n\n const res = await ssrfSafeFetch(url, {\n method: 'GET',\n headers,\n allowPrivateIp: args.allowPrivateIp,\n });\n\n if (hop === 0 && res.status === 304) {\n return {\n status: 'not_modified',\n finalUrl: url,\n data: null,\n ...(res.headers['etag'] && { etag: res.headers['etag'] }),\n ...(res.headers['cache-control'] && { cacheControl: res.headers['cache-control'] }),\n };\n }\n if (res.status !== 200) {\n throw new BrandJsonResolverError('fetch_failed', `brand.json fetch returned HTTP ${res.status}`);\n }\n\n const text = Buffer.from(res.body).toString('utf8');\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new BrandJsonResolverError('invalid_body', `brand.json response is not valid JSON`);\n }\n if (!parsed || typeof parsed !== 'object') {\n throw new BrandJsonResolverError('invalid_body', `brand.json response is not an object`);\n }\n\n const obj = parsed as Record<string, unknown>;\n const authoritative = typeof obj.authoritative_location === 'string' ? obj.authoritative_location : undefined;\n const house = typeof obj.house === 'string' ? obj.house : undefined;\n\n if (authoritative !== undefined) {\n if (hop === args.maxRedirects) {\n throw new BrandJsonResolverError('redirect_depth_exceeded', `brand.json redirect depth exceeded`);\n }\n url = canonicalizeUrl(authoritative, args.allowPrivateIp);\n continue;\n }\n if (house !== undefined) {\n // The \"house string\" redirect variant: a bare domain pointing at the\n // authoritative portfolio. Reject anything that isn't a bare hostname\n // so an attacker can't inject userinfo, paths, or ports via the\n // interpolation.\n if (!BARE_HOSTNAME.test(house)) {\n throw new BrandJsonResolverError('invalid_house', `brand.json \"house\" is not a bare hostname`);\n }\n if (hop === args.maxRedirects) {\n throw new BrandJsonResolverError('redirect_depth_exceeded', `brand.json redirect depth exceeded`);\n }\n url = canonicalizeUrl(`https://${house}/.well-known/brand.json`, args.allowPrivateIp);\n continue;\n }\n\n // Narrow shape validation on the terminal document. Full BrandJsonSchema\n // validation is stricter than we need (it enforces `^https://` on URLs,\n // which ssrfSafeFetch already polices) and fails too readily on trailing\n // portfolio fields the resolver doesn't touch. What we MUST reject: a\n // document whose shape would let an attacker smuggle a non-string url or\n // jwks_uri past the selector.\n assertBrandJsonShape(obj);\n\n return {\n status: 'ok',\n finalUrl: url,\n data: obj,\n ...(res.headers['etag'] && { etag: res.headers['etag'] }),\n ...(res.headers['cache-control'] && { cacheControl: res.headers['cache-control'] }),\n };\n }\n\n throw new BrandJsonResolverError('redirect_depth_exceeded', `brand.json redirect depth exceeded`);\n}\n\n/**\n * Structurally validate a URL and return it in a canonical form for the\n * loop-detection `Set`. Rejects URLs that `ssrfSafeFetch` would later refuse\n * anyway — but catching them here gives a clearer error code and prevents\n * a malformed `authoritative_location` from silently bypassing the hop cap\n * because its string form differed from a prior seen URL.\n */\nfunction canonicalizeUrl(raw: string, allowPrivateIp: boolean): string {\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new BrandJsonResolverError('invalid_url', `brand.json URL is malformed`);\n }\n if (parsed.username || parsed.password) {\n throw new BrandJsonResolverError('invalid_url', `brand.json URL must not include userinfo`);\n }\n if (parsed.protocol !== 'https:' && !(allowPrivateIp && parsed.protocol === 'http:')) {\n throw new BrandJsonResolverError('invalid_url', `brand.json URL must use https://`);\n }\n // Fragments are not sent on the wire and must not smuggle loop-detection\n // aliases — strip them before stashing in `seen`.\n parsed.hash = '';\n return parsed.toString();\n}\n\nfunction isPortfolioHouse(value: unknown): boolean {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Walk every `agents[]` array we might consult and reject entries where\n * `url` or `jwks_uri` are present but non-string. A permissive walk here\n * catches a malformed document that `pickAgent` would otherwise silently\n * skip (a non-string url gets filtered out, so an attacker who declares\n * two agents of a type — one well-formed and one with a poisoned shape —\n * couldn't change the selector outcome, but schema-invalid payloads are\n * still a strong signal of compromise).\n */\nfunction assertBrandJsonShape(obj: Record<string, unknown>): void {\n const queues: unknown[] = [obj.agents];\n if (isPortfolioHouse(obj.house)) {\n const house = obj.house as Record<string, unknown>;\n queues.push(house.agents);\n if (Array.isArray(obj.brands)) {\n for (const brand of obj.brands as Record<string, unknown>[]) {\n if (brand) queues.push(brand.agents);\n }\n }\n }\n for (const q of queues) {\n if (q === undefined) continue;\n if (!Array.isArray(q)) {\n throw new BrandJsonResolverError('schema_invalid', 'brand.json `agents` must be an array');\n }\n for (const entry of q) {\n if (entry && typeof entry === 'object') {\n const e = entry as AgentEntry;\n if (e.url !== undefined && typeof e.url !== 'string') {\n throw new BrandJsonResolverError('schema_invalid', 'brand.json agent.url must be a string');\n }\n if (e.jwks_uri !== undefined && typeof e.jwks_uri !== 'string') {\n throw new BrandJsonResolverError('schema_invalid', 'brand.json agent.jwks_uri must be a string');\n }\n }\n }\n }\n}\n\n/** An agent entry as declared in brand.json `agents[]`. */\ninterface AgentEntry {\n type?: string;\n url?: string;\n id?: string;\n jwks_uri?: string;\n}\n\nfunction selectAgent(\n data: unknown,\n finalBrandUrl: string,\n selector: { agentType: BrandAgentType; agentId?: string; brandId?: string }\n): SelectedAgent {\n if (!data || typeof data !== 'object') {\n throw new BrandJsonResolverError(\n 'agent_not_found',\n `brand.json has no agent matching ${describeSelector(selector)}`\n );\n }\n const obj = data as Record<string, unknown>;\n\n let picked: SelectedAgent | undefined;\n if (isPortfolioHouse(obj.house)) {\n const house = obj.house as Record<string, unknown>;\n if (selector.brandId !== undefined) {\n const brands = Array.isArray(obj.brands) ? (obj.brands as Record<string, unknown>[]) : [];\n const brand = brands.find(b => b && b.id === selector.brandId);\n if (brand) picked = pickAgent(brand.agents, finalBrandUrl, selector);\n }\n picked ??= pickAgent(house.agents, finalBrandUrl, selector);\n } else {\n picked = pickAgent(obj.agents, finalBrandUrl, selector);\n }\n\n if (!picked) {\n throw new BrandJsonResolverError(\n 'agent_not_found',\n `brand.json has no agent matching ${describeSelector(selector)}`\n );\n }\n return picked;\n}\n\nfunction pickAgent(\n agents: unknown,\n finalBrandUrl: string,\n selector: { agentType: BrandAgentType; agentId?: string }\n): SelectedAgent | undefined {\n if (!Array.isArray(agents)) return undefined;\n const matches = agents.filter((a): a is AgentEntry => {\n if (!a || typeof a !== 'object') return false;\n const e = a as AgentEntry;\n if (e.type !== selector.agentType) return false;\n if (selector.agentId !== undefined && e.id !== selector.agentId) return false;\n return typeof e.url === 'string';\n });\n if (matches.length === 0) return undefined;\n if (matches.length > 1 && selector.agentId === undefined) {\n throw new BrandJsonResolverError(\n 'agent_ambiguous',\n `brand.json declares ${matches.length} agents of type \"${selector.agentType}\"; ` +\n `pass \\`agentId\\` to disambiguate (choices: ${matches.map(m => m.id ?? '<no-id>').join(', ')})`\n );\n }\n const agent = matches[0]!;\n const url = agent.url!;\n const jwksUri = agent.jwks_uri ?? defaultJwksUri(url, finalBrandUrl);\n return { url, jwksUri };\n}\n\n/**\n * Spec fallback: \"When absent, verifiers MUST default to /.well-known/jwks.json\n * on the origin of `url`.\" We strip any path/query/fragment from the agent\n * URL and replace it with the well-known path.\n *\n * Security: require the agent origin to match the final brand.json origin.\n * Without this check, an attacker-controlled brand.json could set\n * `agent.url: \"https://victim-internal.example/\"` and force the verifier to\n * treat that origin's JWKS as authoritative — a cross-origin trust pivot.\n * Publishers that genuinely host their agent on a different origin from\n * their brand.json MUST declare an explicit `jwks_uri` (and that URI is\n * validated at fetch time by the inner HttpsJwksResolver, not here).\n */\nfunction defaultJwksUri(agentUrl: string, finalBrandUrl: string): string {\n let agent: URL;\n try {\n agent = new URL(agentUrl);\n } catch {\n throw new BrandJsonResolverError('invalid_url', `agent.url is not a valid URL`);\n }\n const brand = new URL(finalBrandUrl);\n if (agent.origin !== brand.origin) {\n throw new BrandJsonResolverError(\n 'jwks_origin_mismatch',\n `agent.url origin (${agent.origin}) does not match brand.json origin (${brand.origin}); ` +\n `publisher must declare an explicit jwks_uri for cross-origin agents`\n );\n }\n return `${agent.origin}/.well-known/jwks.json`;\n}\n\nfunction describeSelector(selector: { agentType: BrandAgentType; agentId?: string; brandId?: string }): string {\n const parts = [`type=${selector.agentType}`];\n if (selector.agentId !== undefined) parts.push(`id=${selector.agentId}`);\n if (selector.brandId !== undefined) parts.push(`brand=${selector.brandId}`);\n return parts.join(' ');\n}\n\nfunction computeLifetime(cacheControl: string | undefined, maxAge: number): number {\n if (!cacheControl) return maxAge;\n const lower = cacheControl.toLowerCase();\n if (/\\bno-store\\b|\\bno-cache\\b/.test(lower)) return 0;\n const match = /max-age\\s*=\\s*(\\d+)/.exec(lower);\n if (match) {\n const serverMax = Number(match[1]);\n if (Number.isFinite(serverMax)) return Math.min(serverMax, maxAge);\n }\n return maxAge;\n}\n"],"mappings":"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","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { RequestSignatureError } from "./errors.mjs";
8
2
  const DEFAULT_PARAM_ORDER = [
9
3
  "created",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/canonicalize.ts"],"sourcesContent":["import { RequestSignatureError } from './errors';\n\nexport interface RequestLike {\n method: string;\n url: string;\n headers: Record<string, string | string[] | undefined>;\n body?: string;\n}\n\n/**\n * RFC 9421 response-signing context. Carries the response status and\n * headers/body, plus the originating request method + URL so derived\n * components that bind back to the request context (`@method`,\n * `@target-uri`, `@authority`) resolve correctly.\n */\nexport interface ResponseLike {\n status: number;\n headers: Record<string, string | string[] | undefined>;\n body?: string;\n /**\n * Originating request context. `url` must be absolute because\n * `@target-uri` and `@authority` are parsed with `new URL(...)`. Supply\n * `headers` when signing request-qualified header components such as\n * `authorization;req`.\n */\n request: { method: string; url: string; headers?: Record<string, string | string[] | undefined> };\n}\n\nexport interface SignatureParams {\n created: number;\n expires: number;\n nonce: string;\n keyid: string;\n alg: string;\n tag: string;\n}\n\nconst DEFAULT_PARAM_ORDER: ReadonlyArray<keyof SignatureParams> = [\n 'created',\n 'expires',\n 'nonce',\n 'keyid',\n 'alg',\n 'tag',\n];\n\nconst STRING_PARAMS = new Set<keyof SignatureParams>(['nonce', 'keyid', 'alg', 'tag']);\n\nconst SUPPORTED_DERIVED = new Set(['@method', '@target-uri', '@authority', '@status']);\n\nexport function canonicalTargetUri(rawUrl: string): string {\n rejectNonAsciiHost(rawUrl);\n const u = new URL(rawUrl);\n if (u.username || u.password) {\n throw new RequestSignatureError(\n 'request_signature_header_malformed',\n 1,\n '@target-uri must not include userinfo; strip credentials before signing'\n );\n }\n const assembled = `${u.protocol}//${u.host}${u.pathname}${u.search}`;\n return uppercasePercentEncoding(decodeUnreservedPercentEncoding(assembled));\n}\n\nexport function canonicalAuthority(rawUrl: string): string {\n rejectNonAsciiHost(rawUrl);\n const u = new URL(rawUrl);\n if (u.username || u.password) {\n throw new RequestSignatureError(\n 'request_signature_header_malformed',\n 1,\n '@authority must not include userinfo; strip credentials before signing'\n );\n }\n return u.host.toLowerCase();\n}\n\nexport function canonicalMethod(method: string): string {\n return method.toUpperCase();\n}\n\nexport function getHeaderValue(\n headers: Record<string, string | string[] | undefined>,\n name: string\n): string | undefined {\n const lower = name.toLowerCase();\n for (const [k, v] of Object.entries(headers)) {\n if (k.toLowerCase() === lower) {\n if (v === undefined) return undefined;\n if (Array.isArray(v)) {\n return v.map(entry => entry.trim()).join(', ');\n }\n return v.trim();\n }\n }\n return undefined;\n}\n\n/**\n * Build the RFC 9421 §2.5 signature base.\n *\n * When `signatureParamsValue` is supplied (verifier path), the function emits\n * it verbatim as the value of the `@signature-params` line — this preserves\n * byte-identity with the `Signature-Input` header a peer actually sent, even\n * if their param order differs from ours. When omitted (signer path), the\n * function formats from `params` using a fixed canonical order.\n */\nexport function buildSignatureBase(\n components: ReadonlyArray<string>,\n request: RequestLike,\n params: SignatureParams,\n signatureParamsValue?: string\n): string {\n const lines: string[] = [];\n for (const component of components) {\n const value = resolveComponentValue(component, request);\n if (value === undefined) {\n throw new RequestSignatureError(\n 'request_signature_components_incomplete',\n 6,\n `Covered component \"${component}\" not present in request`\n );\n }\n lines.push(`${formatComponentIdentifier(component)}: ${value}`);\n }\n const paramsString = signatureParamsValue ?? formatSignatureParams(components, params);\n lines.push(`\"@signature-params\": ${paramsString}`);\n return lines.join('\\n');\n}\n\n/**\n * Build the RFC 9421 §2.5 signature base for a response.\n *\n * Resolves `@status` from `response.status`; request-qualified components\n * such as `@method;req`, `@target-uri;req`, and `@authority;req` bind to\n * `response.request`, request-qualified headers bind to\n * `response.request.headers`, and response header components resolve against\n * `response.headers`. `signatureParamsValue` has the same verifier-path\n * meaning as in {@link buildSignatureBase}.\n */\nexport function buildResponseSignatureBase(\n components: ReadonlyArray<string>,\n response: ResponseLike,\n params: SignatureParams,\n signatureParamsValue?: string\n): string {\n const requestView: RequestLike = {\n method: response.request.method,\n url: response.request.url,\n headers: response.request.headers ?? {},\n };\n const lines: string[] = [];\n for (const component of components) {\n const { bare, requestBound } = parseComponentIdentifier(component);\n const value = resolveResponseComponentValue(bare, requestBound, response, requestView);\n if (value === undefined) {\n throw new RequestSignatureError(\n 'request_signature_components_incomplete',\n 6,\n `Covered component \"${component}\" not present in response`\n );\n }\n lines.push(`${formatComponentIdentifier(component)}: ${value}`);\n }\n const paramsString = signatureParamsValue ?? formatSignatureParams(components, params);\n lines.push(`\"@signature-params\": ${paramsString}`);\n return lines.join('\\n');\n}\n\nexport function formatSignatureParams(components: ReadonlyArray<string>, params: SignatureParams): string {\n const componentList = components.map(formatComponentIdentifier).join(' ');\n const paramPairs: string[] = [];\n for (const key of DEFAULT_PARAM_ORDER) {\n const raw = params[key];\n if (raw === undefined) continue;\n paramPairs.push(STRING_PARAMS.has(key) ? `${key}=\"${raw}\"` : `${key}=${raw}`);\n }\n return `(${componentList});${paramPairs.join(';')}`;\n}\n\nfunction parseComponentIdentifier(component: string): { bare: string; requestBound: boolean } {\n if (!component.includes(';')) return { bare: component, requestBound: false };\n const [bare, ...params] = component.split(';');\n const unsupported = params.filter(param => param !== 'req');\n if (unsupported.length > 0) {\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n `Covered component \"${component}\" uses unsupported component parameters`\n );\n }\n return {\n bare: bare ?? component,\n requestBound: params.includes('req'),\n };\n}\n\nfunction formatComponentIdentifier(component: string): string {\n const { bare, requestBound } = parseComponentIdentifier(component);\n return `\"${bare}\"${requestBound ? ';req' : ''}`;\n}\n\nfunction resolveResponseComponentValue(\n bare: string,\n requestBound: boolean,\n response: ResponseLike,\n requestView: RequestLike\n): string | undefined {\n if (bare === '@status') {\n if (requestBound) {\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n '\"@status\" cannot use the request-bound ;req parameter'\n );\n }\n return String(response.status);\n }\n if (bare.startsWith('@')) {\n if (!requestBound) {\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n `Response derived component \"${bare}\" must use the request-bound ;req parameter`\n );\n }\n return resolveComponentValue(bare, requestView);\n }\n return getHeaderValue(requestBound ? requestView.headers : response.headers, bare);\n}\n\nfunction resolveComponentValue(component: string, request: RequestLike): string | undefined {\n if (component.startsWith('@')) {\n if (!SUPPORTED_DERIVED.has(component)) {\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n `Derived component \"${component}\" is not supported by the AdCP request-signing profile`\n );\n }\n switch (component) {\n case '@method':\n return canonicalMethod(request.method);\n case '@target-uri':\n return canonicalTargetUri(request.url);\n case '@authority':\n return canonicalAuthority(request.url);\n case '@status':\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n '\"@status\" is only valid in response-signing context; use buildResponseSignatureBase'\n );\n }\n }\n return getHeaderValue(request.headers, component);\n}\n\nfunction uppercasePercentEncoding(input: string): string {\n return input.replace(/%([0-9a-fA-F]{2})/g, (_m, hex: string) => `%${hex.toUpperCase()}`);\n}\n\n/**\n * RFC 3986 §6.2.2.2: percent-encoded triplets of unreserved characters\n * (ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\") MUST be decoded to their literal\n * form during URI normalization. The spec's RFC 9421 profile step 6\n * (`@target-uri` canonicalization) requires this decode alongside the\n * uppercase-hex pass — a verifier that uppercases but does not decode will\n * produce a `%7E`-vs-`~` mismatch against a signer that decoded correctly.\n */\nfunction decodeUnreservedPercentEncoding(input: string): string {\n return input.replace(/%([0-9a-fA-F]{2})/g, (match, hex: string) => {\n const code = parseInt(hex, 16);\n // Unreserved: A-Z (0x41-0x5A), a-z (0x61-0x7A), 0-9 (0x30-0x39),\n // \"-\" (0x2D), \".\" (0x2E), \"_\" (0x5F), \"~\" (0x7E).\n const isUnreserved =\n (code >= 0x41 && code <= 0x5a) ||\n (code >= 0x61 && code <= 0x7a) ||\n (code >= 0x30 && code <= 0x39) ||\n code === 0x2d ||\n code === 0x2e ||\n code === 0x5f ||\n code === 0x7e;\n return isUnreserved ? String.fromCharCode(code) : match;\n });\n}\n\n/**\n * Raw non-ASCII bytes in the URL authority (IDN U-label) are a parse-time\n * anomaly — AdCP @target-uri canonicalization expects A-labels (Punycode).\n * Reject rather than implicitly normalize: UTS-46 transitional vs.\n * non-transitional produce different A-labels for the same input, which\n * would open a signer/verifier canonicalization differential. Accepts\n * both absolute (`scheme://…`) and scheme-relative (`//…`) URL shapes.\n */\nexport function rejectNonAsciiHost(rawUrl: string): void {\n const authorityMatch = rawUrl.match(/^(?:[a-z][a-z0-9+.\\-]*:)?\\/\\/([^/?#]*)/i);\n if (!authorityMatch) return;\n const authority = authorityMatch[1]!;\n for (let i = 0; i < authority.length; i++) {\n if (authority.charCodeAt(i) > 0x7f) {\n throw new RequestSignatureError(\n 'request_signature_header_malformed',\n 1,\n 'URL authority contains non-ASCII bytes; use the A-label (Punycode) form'\n );\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/canonicalize.ts"],"sourcesContent":["import { RequestSignatureError } from './errors';\n\nexport interface RequestLike {\n method: string;\n url: string;\n headers: Record<string, string | string[] | undefined>;\n body?: string;\n}\n\n/**\n * RFC 9421 response-signing context. Carries the response status and\n * headers/body, plus the originating request method + URL so derived\n * components that bind back to the request context (`@method`,\n * `@target-uri`, `@authority`) resolve correctly.\n */\nexport interface ResponseLike {\n status: number;\n headers: Record<string, string | string[] | undefined>;\n body?: string;\n /**\n * Originating request context. `url` must be absolute because\n * `@target-uri` and `@authority` are parsed with `new URL(...)`. Supply\n * `headers` when signing request-qualified header components such as\n * `authorization;req`.\n */\n request: { method: string; url: string; headers?: Record<string, string | string[] | undefined> };\n}\n\nexport interface SignatureParams {\n created: number;\n expires: number;\n nonce: string;\n keyid: string;\n alg: string;\n tag: string;\n}\n\nconst DEFAULT_PARAM_ORDER: ReadonlyArray<keyof SignatureParams> = [\n 'created',\n 'expires',\n 'nonce',\n 'keyid',\n 'alg',\n 'tag',\n];\n\nconst STRING_PARAMS = new Set<keyof SignatureParams>(['nonce', 'keyid', 'alg', 'tag']);\n\nconst SUPPORTED_DERIVED = new Set(['@method', '@target-uri', '@authority', '@status']);\n\nexport function canonicalTargetUri(rawUrl: string): string {\n rejectNonAsciiHost(rawUrl);\n const u = new URL(rawUrl);\n if (u.username || u.password) {\n throw new RequestSignatureError(\n 'request_signature_header_malformed',\n 1,\n '@target-uri must not include userinfo; strip credentials before signing'\n );\n }\n const assembled = `${u.protocol}//${u.host}${u.pathname}${u.search}`;\n return uppercasePercentEncoding(decodeUnreservedPercentEncoding(assembled));\n}\n\nexport function canonicalAuthority(rawUrl: string): string {\n rejectNonAsciiHost(rawUrl);\n const u = new URL(rawUrl);\n if (u.username || u.password) {\n throw new RequestSignatureError(\n 'request_signature_header_malformed',\n 1,\n '@authority must not include userinfo; strip credentials before signing'\n );\n }\n return u.host.toLowerCase();\n}\n\nexport function canonicalMethod(method: string): string {\n return method.toUpperCase();\n}\n\nexport function getHeaderValue(\n headers: Record<string, string | string[] | undefined>,\n name: string\n): string | undefined {\n const lower = name.toLowerCase();\n for (const [k, v] of Object.entries(headers)) {\n if (k.toLowerCase() === lower) {\n if (v === undefined) return undefined;\n if (Array.isArray(v)) {\n return v.map(entry => entry.trim()).join(', ');\n }\n return v.trim();\n }\n }\n return undefined;\n}\n\n/**\n * Build the RFC 9421 §2.5 signature base.\n *\n * When `signatureParamsValue` is supplied (verifier path), the function emits\n * it verbatim as the value of the `@signature-params` line — this preserves\n * byte-identity with the `Signature-Input` header a peer actually sent, even\n * if their param order differs from ours. When omitted (signer path), the\n * function formats from `params` using a fixed canonical order.\n */\nexport function buildSignatureBase(\n components: ReadonlyArray<string>,\n request: RequestLike,\n params: SignatureParams,\n signatureParamsValue?: string\n): string {\n const lines: string[] = [];\n for (const component of components) {\n const value = resolveComponentValue(component, request);\n if (value === undefined) {\n throw new RequestSignatureError(\n 'request_signature_components_incomplete',\n 6,\n `Covered component \"${component}\" not present in request`\n );\n }\n lines.push(`${formatComponentIdentifier(component)}: ${value}`);\n }\n const paramsString = signatureParamsValue ?? formatSignatureParams(components, params);\n lines.push(`\"@signature-params\": ${paramsString}`);\n return lines.join('\\n');\n}\n\n/**\n * Build the RFC 9421 §2.5 signature base for a response.\n *\n * Resolves `@status` from `response.status`; request-qualified components\n * such as `@method;req`, `@target-uri;req`, and `@authority;req` bind to\n * `response.request`, request-qualified headers bind to\n * `response.request.headers`, and response header components resolve against\n * `response.headers`. `signatureParamsValue` has the same verifier-path\n * meaning as in {@link buildSignatureBase}.\n */\nexport function buildResponseSignatureBase(\n components: ReadonlyArray<string>,\n response: ResponseLike,\n params: SignatureParams,\n signatureParamsValue?: string\n): string {\n const requestView: RequestLike = {\n method: response.request.method,\n url: response.request.url,\n headers: response.request.headers ?? {},\n };\n const lines: string[] = [];\n for (const component of components) {\n const { bare, requestBound } = parseComponentIdentifier(component);\n const value = resolveResponseComponentValue(bare, requestBound, response, requestView);\n if (value === undefined) {\n throw new RequestSignatureError(\n 'request_signature_components_incomplete',\n 6,\n `Covered component \"${component}\" not present in response`\n );\n }\n lines.push(`${formatComponentIdentifier(component)}: ${value}`);\n }\n const paramsString = signatureParamsValue ?? formatSignatureParams(components, params);\n lines.push(`\"@signature-params\": ${paramsString}`);\n return lines.join('\\n');\n}\n\nexport function formatSignatureParams(components: ReadonlyArray<string>, params: SignatureParams): string {\n const componentList = components.map(formatComponentIdentifier).join(' ');\n const paramPairs: string[] = [];\n for (const key of DEFAULT_PARAM_ORDER) {\n const raw = params[key];\n if (raw === undefined) continue;\n paramPairs.push(STRING_PARAMS.has(key) ? `${key}=\"${raw}\"` : `${key}=${raw}`);\n }\n return `(${componentList});${paramPairs.join(';')}`;\n}\n\nfunction parseComponentIdentifier(component: string): { bare: string; requestBound: boolean } {\n if (!component.includes(';')) return { bare: component, requestBound: false };\n const [bare, ...params] = component.split(';');\n const unsupported = params.filter(param => param !== 'req');\n if (unsupported.length > 0) {\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n `Covered component \"${component}\" uses unsupported component parameters`\n );\n }\n return {\n bare: bare ?? component,\n requestBound: params.includes('req'),\n };\n}\n\nfunction formatComponentIdentifier(component: string): string {\n const { bare, requestBound } = parseComponentIdentifier(component);\n return `\"${bare}\"${requestBound ? ';req' : ''}`;\n}\n\nfunction resolveResponseComponentValue(\n bare: string,\n requestBound: boolean,\n response: ResponseLike,\n requestView: RequestLike\n): string | undefined {\n if (bare === '@status') {\n if (requestBound) {\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n '\"@status\" cannot use the request-bound ;req parameter'\n );\n }\n return String(response.status);\n }\n if (bare.startsWith('@')) {\n if (!requestBound) {\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n `Response derived component \"${bare}\" must use the request-bound ;req parameter`\n );\n }\n return resolveComponentValue(bare, requestView);\n }\n return getHeaderValue(requestBound ? requestView.headers : response.headers, bare);\n}\n\nfunction resolveComponentValue(component: string, request: RequestLike): string | undefined {\n if (component.startsWith('@')) {\n if (!SUPPORTED_DERIVED.has(component)) {\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n `Derived component \"${component}\" is not supported by the AdCP request-signing profile`\n );\n }\n switch (component) {\n case '@method':\n return canonicalMethod(request.method);\n case '@target-uri':\n return canonicalTargetUri(request.url);\n case '@authority':\n return canonicalAuthority(request.url);\n case '@status':\n throw new RequestSignatureError(\n 'request_signature_components_unexpected',\n 6,\n '\"@status\" is only valid in response-signing context; use buildResponseSignatureBase'\n );\n }\n }\n return getHeaderValue(request.headers, component);\n}\n\nfunction uppercasePercentEncoding(input: string): string {\n return input.replace(/%([0-9a-fA-F]{2})/g, (_m, hex: string) => `%${hex.toUpperCase()}`);\n}\n\n/**\n * RFC 3986 §6.2.2.2: percent-encoded triplets of unreserved characters\n * (ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\") MUST be decoded to their literal\n * form during URI normalization. The spec's RFC 9421 profile step 6\n * (`@target-uri` canonicalization) requires this decode alongside the\n * uppercase-hex pass — a verifier that uppercases but does not decode will\n * produce a `%7E`-vs-`~` mismatch against a signer that decoded correctly.\n */\nfunction decodeUnreservedPercentEncoding(input: string): string {\n return input.replace(/%([0-9a-fA-F]{2})/g, (match, hex: string) => {\n const code = parseInt(hex, 16);\n // Unreserved: A-Z (0x41-0x5A), a-z (0x61-0x7A), 0-9 (0x30-0x39),\n // \"-\" (0x2D), \".\" (0x2E), \"_\" (0x5F), \"~\" (0x7E).\n const isUnreserved =\n (code >= 0x41 && code <= 0x5a) ||\n (code >= 0x61 && code <= 0x7a) ||\n (code >= 0x30 && code <= 0x39) ||\n code === 0x2d ||\n code === 0x2e ||\n code === 0x5f ||\n code === 0x7e;\n return isUnreserved ? String.fromCharCode(code) : match;\n });\n}\n\n/**\n * Raw non-ASCII bytes in the URL authority (IDN U-label) are a parse-time\n * anomaly — AdCP @target-uri canonicalization expects A-labels (Punycode).\n * Reject rather than implicitly normalize: UTS-46 transitional vs.\n * non-transitional produce different A-labels for the same input, which\n * would open a signer/verifier canonicalization differential. Accepts\n * both absolute (`scheme://…`) and scheme-relative (`//…`) URL shapes.\n */\nexport function rejectNonAsciiHost(rawUrl: string): void {\n const authorityMatch = rawUrl.match(/^(?:[a-z][a-z0-9+.\\-]*:)?\\/\\/([^/?#]*)/i);\n if (!authorityMatch) return;\n const authority = authorityMatch[1]!;\n for (let i = 0; i < authority.length; i++) {\n if (authority.charCodeAt(i) > 0x7f) {\n throw new RequestSignatureError(\n 'request_signature_header_malformed',\n 1,\n 'URL authority contains non-ASCII bytes; use the A-label (Punycode) form'\n );\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { createHash } from "node:crypto";
8
2
  const DEFAULT_TTL_SECONDS = 300;
9
3
  class CapabilityCache {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/capability-cache.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type { VerifierCapability } from './types';\n\nexport interface CachedCapability {\n /** RFC 9421 request-signing capability block as advertised by the agent. */\n requestSigning: VerifierCapability | undefined;\n /** AdCP major version associated with the capability response, when known. */\n adcpVersion: number | undefined;\n /** Epoch seconds when this entry was written. */\n fetchedAt: number;\n /**\n * Optional explicit epoch-seconds deadline at which this entry becomes\n * stale. Overrides the cache's default TTL — used to give negative\n * (failed-discovery) entries a shorter refresh window than positive\n * entries so a transient seller outage doesn't block signing decisions\n * for the full 5-minute TTL.\n */\n staleAt?: number;\n}\n\nexport interface CapabilityCacheOptions {\n /** Seconds before a cached capability is considered stale. Default 300. */\n ttlSeconds?: number;\n now?: () => number;\n}\n\nconst DEFAULT_TTL_SECONDS = 300;\n\n/**\n * Per-agent cache of the `request_signing` capability block returned by\n * `get_adcp_capabilities`. Keyed by a caller-supplied `cacheKey` (typically\n * `agent_uri + auth-token-hash`) so that different credentials or URLs get\n * independent entries.\n *\n * Staleness is TTL-based; callers may also invalidate explicitly — e.g. after\n * a seller rotates its advertisement mid-session — so the next outbound call\n * re-fetches before deciding whether to sign.\n */\nexport class CapabilityCache {\n private readonly entries = new Map<string, CachedCapability>();\n /**\n * In-flight priming fetches keyed by `cacheKey`. Lives on the instance so\n * two `CapabilityCache` objects — e.g., one per tenant in a multi-tenant\n * embedding — don't share an `ensureCapabilityLoaded` promise map across\n * instances and race each other's writes. The default process-global\n * cache uses its own map via `defaultCapabilityCache`.\n */\n private readonly inFlight = new Map<string, Promise<CachedCapability>>();\n private readonly ttlSeconds: number;\n private readonly now: () => number;\n\n constructor(options: CapabilityCacheOptions = {}) {\n this.ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;\n this.now = options.now ?? (() => Math.floor(Date.now() / 1000));\n }\n\n get(cacheKey: string): CachedCapability | undefined {\n return this.entries.get(cacheKey);\n }\n\n set(cacheKey: string, entry: CachedCapability): void {\n this.entries.set(cacheKey, entry);\n }\n\n invalidate(cacheKey: string): void {\n this.entries.delete(cacheKey);\n }\n\n clear(): void {\n this.entries.clear();\n this.inFlight.clear();\n }\n\n isStale(entry: CachedCapability | undefined): boolean {\n if (!entry) return true;\n const now = this.now();\n if (entry.staleAt !== undefined) return now >= entry.staleAt;\n return now - entry.fetchedAt > this.ttlSeconds;\n }\n\n /** @internal Pending-fetch table used by `ensureCapabilityLoaded`. */\n _getInFlight(cacheKey: string): Promise<CachedCapability> | undefined {\n return this.inFlight.get(cacheKey);\n }\n\n /** @internal */\n _setInFlight(cacheKey: string, promise: Promise<CachedCapability>): void {\n this.inFlight.set(cacheKey, promise);\n }\n\n /** @internal */\n _deleteInFlight(cacheKey: string): void {\n this.inFlight.delete(cacheKey);\n }\n}\n\n/**\n * Process-global capability cache. Shared by the ProtocolClient priming path\n * and the transport-level signing fetch wrappers so that a single\n * `get_adcp_capabilities` call serves every subsequent signing decision for\n * an agent.\n */\nexport const defaultCapabilityCache = new CapabilityCache();\n\n/**\n * Build a stable cache key from an agent URI, an optional auth-token hash,\n * and an optional signer-key fingerprint. Two callers pointing at the same\n * agent URI under different signing identities get separate entries — a\n * seller can advertise different policies per counterparty key.\n *\n * Hash is a cache-key disambiguator, not a security boundary; a hypothetical\n * collision across users would still transmit only the original caller's\n * token (the cache key is not the auth credential itself).\n */\nexport function buildCapabilityCacheKey(agentUri: string, authToken?: string, signerFingerprint?: string): string {\n const tokenSuffix = authToken ? `::${createHash('sha256').update(authToken).digest('hex').slice(0, 16)}` : '';\n const signerSuffix = signerFingerprint ? `::sig=${signerFingerprint}` : '';\n return `${agentUri}${tokenSuffix}${signerSuffix}`;\n}\n"],"mappings":";;;;;;AAAA,SAAS,kBAAkB;AA0B3B,MAAM,sBAAsB;AAYrB,MAAM,gBAAgB;AAAA,EACV,UAAU,oBAAI,IAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5C,WAAW,oBAAI,IAAuC;AAAA,EACtD;AAAA,EACA;AAAA,EAEjB,YAAY,UAAkC,CAAC,GAAG;AAChD,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,MAAM,QAAQ,QAAQ,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,EAC/D;AAAA,EAEA,IAAI,UAAgD;AAClD,WAAO,KAAK,QAAQ,IAAI,QAAQ;AAAA,EAClC;AAAA,EAEA,IAAI,UAAkB,OAA+B;AACnD,SAAK,QAAQ,IAAI,UAAU,KAAK;AAAA,EAClC;AAAA,EAEA,WAAW,UAAwB;AACjC,SAAK,QAAQ,OAAO,QAAQ;AAAA,EAC9B;AAAA,EAEA,QAAc;AACZ,SAAK,QAAQ,MAAM;AACnB,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EAEA,QAAQ,OAA8C;AACpD,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,YAAY,OAAW,QAAO,OAAO,MAAM;AACrD,WAAO,MAAM,MAAM,YAAY,KAAK;AAAA,EACtC;AAAA;AAAA,EAGA,aAAa,UAAyD;AACpE,WAAO,KAAK,SAAS,IAAI,QAAQ;AAAA,EACnC;AAAA;AAAA,EAGA,aAAa,UAAkB,SAA0C;AACvE,SAAK,SAAS,IAAI,UAAU,OAAO;AAAA,EACrC;AAAA;AAAA,EAGA,gBAAgB,UAAwB;AACtC,SAAK,SAAS,OAAO,QAAQ;AAAA,EAC/B;AACF;AAQO,MAAM,yBAAyB,IAAI,gBAAgB;AAYnD,SAAS,wBAAwB,UAAkB,WAAoB,mBAAoC;AAChH,QAAM,cAAc,YAAY,KAAK,WAAW,QAAQ,EAAE,OAAO,SAAS,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK;AAC3G,QAAM,eAAe,oBAAoB,SAAS,iBAAiB,KAAK;AACxE,SAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY;AACjD;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/capability-cache.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type { VerifierCapability } from './types';\n\nexport interface CachedCapability {\n /** RFC 9421 request-signing capability block as advertised by the agent. */\n requestSigning: VerifierCapability | undefined;\n /** AdCP major version associated with the capability response, when known. */\n adcpVersion: number | undefined;\n /** Epoch seconds when this entry was written. */\n fetchedAt: number;\n /**\n * Optional explicit epoch-seconds deadline at which this entry becomes\n * stale. Overrides the cache's default TTL — used to give negative\n * (failed-discovery) entries a shorter refresh window than positive\n * entries so a transient seller outage doesn't block signing decisions\n * for the full 5-minute TTL.\n */\n staleAt?: number;\n}\n\nexport interface CapabilityCacheOptions {\n /** Seconds before a cached capability is considered stale. Default 300. */\n ttlSeconds?: number;\n now?: () => number;\n}\n\nconst DEFAULT_TTL_SECONDS = 300;\n\n/**\n * Per-agent cache of the `request_signing` capability block returned by\n * `get_adcp_capabilities`. Keyed by a caller-supplied `cacheKey` (typically\n * `agent_uri + auth-token-hash`) so that different credentials or URLs get\n * independent entries.\n *\n * Staleness is TTL-based; callers may also invalidate explicitly — e.g. after\n * a seller rotates its advertisement mid-session — so the next outbound call\n * re-fetches before deciding whether to sign.\n */\nexport class CapabilityCache {\n private readonly entries = new Map<string, CachedCapability>();\n /**\n * In-flight priming fetches keyed by `cacheKey`. Lives on the instance so\n * two `CapabilityCache` objects — e.g., one per tenant in a multi-tenant\n * embedding — don't share an `ensureCapabilityLoaded` promise map across\n * instances and race each other's writes. The default process-global\n * cache uses its own map via `defaultCapabilityCache`.\n */\n private readonly inFlight = new Map<string, Promise<CachedCapability>>();\n private readonly ttlSeconds: number;\n private readonly now: () => number;\n\n constructor(options: CapabilityCacheOptions = {}) {\n this.ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;\n this.now = options.now ?? (() => Math.floor(Date.now() / 1000));\n }\n\n get(cacheKey: string): CachedCapability | undefined {\n return this.entries.get(cacheKey);\n }\n\n set(cacheKey: string, entry: CachedCapability): void {\n this.entries.set(cacheKey, entry);\n }\n\n invalidate(cacheKey: string): void {\n this.entries.delete(cacheKey);\n }\n\n clear(): void {\n this.entries.clear();\n this.inFlight.clear();\n }\n\n isStale(entry: CachedCapability | undefined): boolean {\n if (!entry) return true;\n const now = this.now();\n if (entry.staleAt !== undefined) return now >= entry.staleAt;\n return now - entry.fetchedAt > this.ttlSeconds;\n }\n\n /** @internal Pending-fetch table used by `ensureCapabilityLoaded`. */\n _getInFlight(cacheKey: string): Promise<CachedCapability> | undefined {\n return this.inFlight.get(cacheKey);\n }\n\n /** @internal */\n _setInFlight(cacheKey: string, promise: Promise<CachedCapability>): void {\n this.inFlight.set(cacheKey, promise);\n }\n\n /** @internal */\n _deleteInFlight(cacheKey: string): void {\n this.inFlight.delete(cacheKey);\n }\n}\n\n/**\n * Process-global capability cache. Shared by the ProtocolClient priming path\n * and the transport-level signing fetch wrappers so that a single\n * `get_adcp_capabilities` call serves every subsequent signing decision for\n * an agent.\n */\nexport const defaultCapabilityCache = new CapabilityCache();\n\n/**\n * Build a stable cache key from an agent URI, an optional auth-token hash,\n * and an optional signer-key fingerprint. Two callers pointing at the same\n * agent URI under different signing identities get separate entries — a\n * seller can advertise different policies per counterparty key.\n *\n * Hash is a cache-key disambiguator, not a security boundary; a hypothetical\n * collision across users would still transmit only the original caller's\n * token (the cache key is not the auth credential itself).\n */\nexport function buildCapabilityCacheKey(agentUri: string, authToken?: string, signerFingerprint?: string): string {\n const tokenSuffix = authToken ? `::${createHash('sha256').update(authToken).digest('hex').slice(0, 16)}` : '';\n const signerSuffix = signerFingerprint ? `::sig=${signerFingerprint}` : '';\n return `${agentUri}${tokenSuffix}${signerSuffix}`;\n}\n"],"mappings":"AAAA,SAAS,kBAAkB;AA0B3B,MAAM,sBAAsB;AAYrB,MAAM,gBAAgB;AAAA,EACV,UAAU,oBAAI,IAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5C,WAAW,oBAAI,IAAuC;AAAA,EACtD;AAAA,EACA;AAAA,EAEjB,YAAY,UAAkC,CAAC,GAAG;AAChD,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,MAAM,QAAQ,QAAQ,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,EAC/D;AAAA,EAEA,IAAI,UAAgD;AAClD,WAAO,KAAK,QAAQ,IAAI,QAAQ;AAAA,EAClC;AAAA,EAEA,IAAI,UAAkB,OAA+B;AACnD,SAAK,QAAQ,IAAI,UAAU,KAAK;AAAA,EAClC;AAAA,EAEA,WAAW,UAAwB;AACjC,SAAK,QAAQ,OAAO,QAAQ;AAAA,EAC9B;AAAA,EAEA,QAAc;AACZ,SAAK,QAAQ,MAAM;AACnB,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EAEA,QAAQ,OAA8C;AACpD,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,YAAY,OAAW,QAAO,OAAO,MAAM;AACrD,WAAO,MAAM,MAAM,YAAY,KAAK;AAAA,EACtC;AAAA;AAAA,EAGA,aAAa,UAAyD;AACpE,WAAO,KAAK,SAAS,IAAI,QAAQ;AAAA,EACnC;AAAA;AAAA,EAGA,aAAa,UAAkB,SAA0C;AACvE,SAAK,SAAS,IAAI,UAAU,OAAO;AAAA,EACrC;AAAA;AAAA,EAGA,gBAAgB,UAAwB;AACtC,SAAK,SAAS,OAAO,QAAQ;AAAA,EAC/B;AACF;AAQO,MAAM,yBAAyB,IAAI,gBAAgB;AAYnD,SAAS,wBAAwB,UAAkB,WAAoB,mBAAoC;AAChH,QAAM,cAAc,YAAY,KAAK,WAAW,QAAQ,EAAE,OAAO,SAAS,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK;AAC3G,QAAM,eAAe,oBAAoB,SAAS,iBAAiB,KAAK;AACxE,SAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY;AACjD;","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { unwrapProtocolResponse } from "./protocol-response.mjs";
8
2
  import { isAbortOrTimeoutError } from "../protocols/abort.mjs";
9
3
  const CAPABILITY_OP = "get_adcp_capabilities";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/capability-priming.ts"],"sourcesContent":["import type { AgentConfig } from '../types/adcp';\nimport type { AgentSigningContext } from './agent-context';\nimport type { CachedCapability } from './capability-cache';\nimport { unwrapProtocolResponse } from './protocol-response';\nimport type { VerifierCapability } from './types';\nimport { isAbortOrTimeoutError } from '../protocols/abort';\n\n/**\n * Op name used to fetch the seller's capability advertisement. The signing\n * wrapper short-circuits on this op so the priming request itself is never\n * gated by signing.\n */\nexport const CAPABILITY_OP = 'get_adcp_capabilities';\n\ntype FetchRaw = (args: Record<string, unknown>) => Promise<unknown>;\n\n/**\n * Extract the `request_signing` capability block from a `get_adcp_capabilities`\n * response regardless of how the transport wrapped it:\n *\n * - MCP `CallToolResult` — `structuredContent` or `content[].text` (JSON).\n * - A2A JSON-RPC `SendMessageResponse` — `result` is a `Task` (with\n * `artifacts[].parts[].data`) or a `Message` (with `parts[].data`).\n * - Already-unwrapped payload — returned as-is.\n */\nfunction extractCapability(response: unknown): {\n requestSigning: VerifierCapability | undefined;\n adcpVersion: number | undefined;\n} {\n const payload = unwrapProtocolResponse(response);\n if (!payload || typeof payload !== 'object') return { requestSigning: undefined, adcpVersion: undefined };\n\n const body = payload as Record<string, unknown>;\n const requestSigning = body.request_signing as VerifierCapability | undefined;\n const adcp = body.adcp as { major_versions?: unknown } | undefined;\n const versions = Array.isArray(adcp?.major_versions) ? (adcp!.major_versions as unknown[]) : undefined;\n const adcpVersion =\n versions && versions.length > 0 && typeof versions[0] === 'number' ? (versions[0] as number) : undefined;\n\n return { requestSigning, adcpVersion };\n}\n\n/**\n * Refresh window applied to a negative-cache entry written after a failed\n * discovery call. 60s is short enough that a transient seller outage\n * self-heals on the next user action, long enough to avoid pile-ups if the\n * seller stays down.\n */\nconst NEGATIVE_CACHE_TTL_SECONDS = 60;\n\n/**\n * Populate the capability cache for an agent when the `request_signing` entry\n * is absent or stale. The injected `fetchRaw` callback is expected to make an\n * unsigned `get_adcp_capabilities` call against the counterparty — callers\n * wire it to `ProtocolClient.callTool` or the underlying transport helper so\n * that no new connection code lives here.\n *\n * Fails open: if discovery itself fails, we cache an empty entry with a short\n * `staleAt` window and return it rather than propagating the error. Signing\n * decisions then fall through:\n * - Ops in the buyer's `always_sign` list are still signed (with default\n * content-digest coverage), so explicit pilot opt-ins keep working.\n * - Ops the seller might have listed in `required_for` go out unsigned and\n * are rejected with `request_signature_required` at the wire — the user\n * sees a clear error rather than an opaque priming wedge, and the next\n * retry re-primes.\n */\nexport async function ensureCapabilityLoaded(\n _agent: AgentConfig,\n signingContext: AgentSigningContext,\n fetchRaw: FetchRaw\n): Promise<CachedCapability> {\n const { cache, capabilityCacheKey: key } = signingContext;\n const existing = cache.get(key);\n if (existing && !cache.isStale(existing)) return existing;\n\n const pending = cache._getInFlight(key);\n if (pending) return pending;\n\n const promise = fetchRaw({})\n .then(raw => {\n const { requestSigning, adcpVersion } = extractCapability(raw);\n const entry: CachedCapability = {\n requestSigning,\n adcpVersion,\n fetchedAt: Math.floor(Date.now() / 1000),\n };\n cache.set(key, entry);\n return entry;\n })\n .catch(error => {\n if (isAbortOrTimeoutError(error)) {\n throw error;\n }\n const now = Math.floor(Date.now() / 1000);\n const entry: CachedCapability = {\n requestSigning: undefined,\n adcpVersion: undefined,\n fetchedAt: now,\n staleAt: now + NEGATIVE_CACHE_TTL_SECONDS,\n };\n cache.set(key, entry);\n return entry;\n })\n .finally(() => {\n cache._deleteInFlight(key);\n });\n\n cache._setInFlight(key, promise);\n return promise;\n}\n"],"mappings":";;;;;;AAGA,SAAS,8BAA8B;AAEvC,SAAS,6BAA6B;AAO/B,MAAM,gBAAgB;AAa7B,SAAS,kBAAkB,UAGzB;AACA,QAAM,UAAU,uBAAuB,QAAQ;AAC/C,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO,EAAE,gBAAgB,QAAW,aAAa,OAAU;AAExG,QAAM,OAAO;AACb,QAAM,iBAAiB,KAAK;AAC5B,QAAM,OAAO,KAAK;AAClB,QAAM,WAAW,MAAM,QAAQ,MAAM,cAAc,IAAK,KAAM,iBAA+B;AAC7F,QAAM,cACJ,YAAY,SAAS,SAAS,KAAK,OAAO,SAAS,CAAC,MAAM,WAAY,SAAS,CAAC,IAAe;AAEjG,SAAO,EAAE,gBAAgB,YAAY;AACvC;AAQA,MAAM,6BAA6B;AAmBnC,eAAsB,uBACpB,QACA,gBACA,UAC2B;AAC3B,QAAM,EAAE,OAAO,oBAAoB,IAAI,IAAI;AAC3C,QAAM,WAAW,MAAM,IAAI,GAAG;AAC9B,MAAI,YAAY,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO;AAEjD,QAAM,UAAU,MAAM,aAAa,GAAG;AACtC,MAAI,QAAS,QAAO;AAEpB,QAAM,UAAU,SAAS,CAAC,CAAC,EACxB,KAAK,SAAO;AACX,UAAM,EAAE,gBAAgB,YAAY,IAAI,kBAAkB,GAAG;AAC7D,UAAM,QAA0B;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,IACzC;AACA,UAAM,IAAI,KAAK,KAAK;AACpB,WAAO;AAAA,EACT,CAAC,EACA,MAAM,WAAS;AACd,QAAI,sBAAsB,KAAK,GAAG;AAChC,YAAM;AAAA,IACR;AACA,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,UAAM,QAA0B;AAAA,MAC9B,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,WAAW;AAAA,MACX,SAAS,MAAM;AAAA,IACjB;AACA,UAAM,IAAI,KAAK,KAAK;AACpB,WAAO;AAAA,EACT,CAAC,EACA,QAAQ,MAAM;AACb,UAAM,gBAAgB,GAAG;AAAA,EAC3B,CAAC;AAEH,QAAM,aAAa,KAAK,OAAO;AAC/B,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/capability-priming.ts"],"sourcesContent":["import type { AgentConfig } from '../types/adcp';\nimport type { AgentSigningContext } from './agent-context';\nimport type { CachedCapability } from './capability-cache';\nimport { unwrapProtocolResponse } from './protocol-response';\nimport type { VerifierCapability } from './types';\nimport { isAbortOrTimeoutError } from '../protocols/abort';\n\n/**\n * Op name used to fetch the seller's capability advertisement. The signing\n * wrapper short-circuits on this op so the priming request itself is never\n * gated by signing.\n */\nexport const CAPABILITY_OP = 'get_adcp_capabilities';\n\ntype FetchRaw = (args: Record<string, unknown>) => Promise<unknown>;\n\n/**\n * Extract the `request_signing` capability block from a `get_adcp_capabilities`\n * response regardless of how the transport wrapped it:\n *\n * - MCP `CallToolResult` — `structuredContent` or `content[].text` (JSON).\n * - A2A JSON-RPC `SendMessageResponse` — `result` is a `Task` (with\n * `artifacts[].parts[].data`) or a `Message` (with `parts[].data`).\n * - Already-unwrapped payload — returned as-is.\n */\nfunction extractCapability(response: unknown): {\n requestSigning: VerifierCapability | undefined;\n adcpVersion: number | undefined;\n} {\n const payload = unwrapProtocolResponse(response);\n if (!payload || typeof payload !== 'object') return { requestSigning: undefined, adcpVersion: undefined };\n\n const body = payload as Record<string, unknown>;\n const requestSigning = body.request_signing as VerifierCapability | undefined;\n const adcp = body.adcp as { major_versions?: unknown } | undefined;\n const versions = Array.isArray(adcp?.major_versions) ? (adcp!.major_versions as unknown[]) : undefined;\n const adcpVersion =\n versions && versions.length > 0 && typeof versions[0] === 'number' ? (versions[0] as number) : undefined;\n\n return { requestSigning, adcpVersion };\n}\n\n/**\n * Refresh window applied to a negative-cache entry written after a failed\n * discovery call. 60s is short enough that a transient seller outage\n * self-heals on the next user action, long enough to avoid pile-ups if the\n * seller stays down.\n */\nconst NEGATIVE_CACHE_TTL_SECONDS = 60;\n\n/**\n * Populate the capability cache for an agent when the `request_signing` entry\n * is absent or stale. The injected `fetchRaw` callback is expected to make an\n * unsigned `get_adcp_capabilities` call against the counterparty — callers\n * wire it to `ProtocolClient.callTool` or the underlying transport helper so\n * that no new connection code lives here.\n *\n * Fails open: if discovery itself fails, we cache an empty entry with a short\n * `staleAt` window and return it rather than propagating the error. Signing\n * decisions then fall through:\n * - Ops in the buyer's `always_sign` list are still signed (with default\n * content-digest coverage), so explicit pilot opt-ins keep working.\n * - Ops the seller might have listed in `required_for` go out unsigned and\n * are rejected with `request_signature_required` at the wire — the user\n * sees a clear error rather than an opaque priming wedge, and the next\n * retry re-primes.\n */\nexport async function ensureCapabilityLoaded(\n _agent: AgentConfig,\n signingContext: AgentSigningContext,\n fetchRaw: FetchRaw\n): Promise<CachedCapability> {\n const { cache, capabilityCacheKey: key } = signingContext;\n const existing = cache.get(key);\n if (existing && !cache.isStale(existing)) return existing;\n\n const pending = cache._getInFlight(key);\n if (pending) return pending;\n\n const promise = fetchRaw({})\n .then(raw => {\n const { requestSigning, adcpVersion } = extractCapability(raw);\n const entry: CachedCapability = {\n requestSigning,\n adcpVersion,\n fetchedAt: Math.floor(Date.now() / 1000),\n };\n cache.set(key, entry);\n return entry;\n })\n .catch(error => {\n if (isAbortOrTimeoutError(error)) {\n throw error;\n }\n const now = Math.floor(Date.now() / 1000);\n const entry: CachedCapability = {\n requestSigning: undefined,\n adcpVersion: undefined,\n fetchedAt: now,\n staleAt: now + NEGATIVE_CACHE_TTL_SECONDS,\n };\n cache.set(key, entry);\n return entry;\n })\n .finally(() => {\n cache._deleteInFlight(key);\n });\n\n cache._setInFlight(key, promise);\n return promise;\n}\n"],"mappings":"AAGA,SAAS,8BAA8B;AAEvC,SAAS,6BAA6B;AAO/B,MAAM,gBAAgB;AAa7B,SAAS,kBAAkB,UAGzB;AACA,QAAM,UAAU,uBAAuB,QAAQ;AAC/C,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO,EAAE,gBAAgB,QAAW,aAAa,OAAU;AAExG,QAAM,OAAO;AACb,QAAM,iBAAiB,KAAK;AAC5B,QAAM,OAAO,KAAK;AAClB,QAAM,WAAW,MAAM,QAAQ,MAAM,cAAc,IAAK,KAAM,iBAA+B;AAC7F,QAAM,cACJ,YAAY,SAAS,SAAS,KAAK,OAAO,SAAS,CAAC,MAAM,WAAY,SAAS,CAAC,IAAe;AAEjG,SAAO,EAAE,gBAAgB,YAAY;AACvC;AAQA,MAAM,6BAA6B;AAmBnC,eAAsB,uBACpB,QACA,gBACA,UAC2B;AAC3B,QAAM,EAAE,OAAO,oBAAoB,IAAI,IAAI;AAC3C,QAAM,WAAW,MAAM,IAAI,GAAG;AAC9B,MAAI,YAAY,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO;AAEjD,QAAM,UAAU,MAAM,aAAa,GAAG;AACtC,MAAI,QAAS,QAAO;AAEpB,QAAM,UAAU,SAAS,CAAC,CAAC,EACxB,KAAK,SAAO;AACX,UAAM,EAAE,gBAAgB,YAAY,IAAI,kBAAkB,GAAG;AAC7D,UAAM,QAA0B;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,IACzC;AACA,UAAM,IAAI,KAAK,KAAK;AACpB,WAAO;AAAA,EACT,CAAC,EACA,MAAM,WAAS;AACd,QAAI,sBAAsB,KAAK,GAAG;AAChC,YAAM;AAAA,IACR;AACA,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,UAAM,QAA0B;AAAA,MAC9B,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,WAAW;AAAA,MACX,SAAS,MAAM;AAAA,IACjB;AACA,UAAM,IAAI,KAAK,KAAK;AACpB,WAAO;AAAA,EACT,CAAC,EACA,QAAQ,MAAM;AACb,UAAM,gBAAgB,GAAG;AAAA,EAC3B,CAAC;AAEH,QAAM,aAAa,KAAK,OAAO;AAC/B,SAAO;AACT;","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import {
8
2
  buildResponseSignatureBase,
9
3
  buildSignatureBase,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/client.ts"],"sourcesContent":["/**\n * Client-side signing surface: what a buyer needs to sign outbound AdCP\n * requests per RFC 9421 — signer, canonicalization helpers, fetch wrapper,\n * and the capability cache that gates auto-wiring.\n *\n * Paired with `@adcp/sdk/signing/server` (verifier / middleware / stores).\n * The aggregate `@adcp/sdk/signing` barrel re-exports both for back-compat.\n */\nexport {\n buildResponseSignatureBase,\n buildSignatureBase,\n canonicalAuthority,\n canonicalMethod,\n canonicalTargetUri,\n formatSignatureParams,\n getHeaderValue,\n type RequestLike,\n type ResponseLike,\n type SignatureParams,\n} from './canonicalize';\nexport { computeContentDigest, contentDigestMatches, parseContentDigest } from './content-digest';\nexport {\n requestContextFromExpress,\n requestContextFromFetch,\n requestContextFromLambda,\n type ExpressRequestLike,\n type FetchRequestLike,\n type LambdaRequestEvent,\n type RequestContextFromExpressOptions,\n type RequestContextFromLambdaOptions,\n} from './request-context';\nexport {\n finalizeRequestSignature,\n finalizeResponseSignature,\n prepareRequestSignature,\n prepareResponseSignature,\n prepareWebhookSignature,\n signRequest,\n signResponse,\n signWebhook,\n type PreparedRequestSignature,\n type PreparedResponseSignature,\n type SignatureIdentity,\n type SignedRequest,\n type SignedResponse,\n type SignerKey,\n type SignRequestOptions,\n type SignResponseOptions,\n type SignWebhookOptions,\n} from './signer';\nexport { signRequestAsync, signResponseAsync, signWebhookAsync } from './signer-async';\nexport { derEcdsaToP1363 } from './ecdsa-encoding';\nexport { WEBHOOK_MANDATORY_COMPONENTS, WEBHOOK_SIGNING_TAG } from './webhook-verifier';\nexport { createSigningFetch, type CoverContentDigestPredicate, type SigningFetchOptions } from './fetch';\nexport { createSigningFetchAsync } from './fetch-async';\nexport type { SigningProvider } from './provider';\nexport {\n RequestSignatureError,\n type RequestSignatureErrorCode,\n ResponseSignatureError,\n type ResponseSignatureErrorCode,\n SigningProviderAlgorithmMismatchError,\n type SigningProviderErrorCode,\n WebhookSignatureError,\n type WebhookSignatureErrorCode,\n} from './errors';\nexport {\n ALLOWED_ALGS,\n CLOCK_SKEW_TOLERANCE_SECONDS,\n MANDATORY_COMPONENTS,\n MAX_SIGNATURE_WINDOW_SECONDS,\n REQUEST_SIGNING_TAG,\n RESPONSE_MANDATORY_COMPONENTS,\n RESPONSE_SIGNING_TAG,\n type AdcpJsonWebKey,\n type AdcpSignAlg,\n type ContentDigestPolicy,\n type VerifierCapability,\n} from './types';\nexport {\n CapabilityCache,\n buildCapabilityCacheKey,\n defaultCapabilityCache,\n type CachedCapability,\n type CapabilityCacheOptions,\n} from './capability-cache';\nexport {\n buildAgentSigningFetch,\n createAgentSignedFetch,\n extractAdcpOperation,\n isInlineSigningConfig,\n isProviderSigningConfig,\n resolveCoverContentDigest,\n shouldSignOperation,\n toSignerKey,\n type BuildAgentSigningFetchOptions,\n type CreateAgentSignedFetchOptions,\n} from './agent-fetch';\nexport {\n buildAgentSigningContext,\n signingContextStorage,\n type AgentSigningContext,\n type AgentSigningIdentitySnapshot,\n} from './agent-context';\nexport { ensureCapabilityLoaded, CAPABILITY_OP } from './capability-priming';\nexport { pemToAdcpJwk, type AdcpUse, type PemToAdcpJwkOptions } from './jwks-helpers';\n"],"mappings":";;;;;;AAQA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP,SAAS,sBAAsB,sBAAsB,0BAA0B;AAC/E;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAUK;AACP,SAAS,kBAAkB,mBAAmB,wBAAwB;AACtE,SAAS,uBAAuB;AAChC,SAAS,8BAA8B,2BAA2B;AAClE,SAAS,0BAAsF;AAC/F,SAAS,+BAA+B;AAExC;AAAA,EACE;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP,SAAS,wBAAwB,qBAAqB;AACtD,SAAS,oBAA4D;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/client.ts"],"sourcesContent":["/**\n * Client-side signing surface: what a buyer needs to sign outbound AdCP\n * requests per RFC 9421 — signer, canonicalization helpers, fetch wrapper,\n * and the capability cache that gates auto-wiring.\n *\n * Paired with `@adcp/sdk/signing/server` (verifier / middleware / stores).\n * The aggregate `@adcp/sdk/signing` barrel re-exports both for back-compat.\n */\nexport {\n buildResponseSignatureBase,\n buildSignatureBase,\n canonicalAuthority,\n canonicalMethod,\n canonicalTargetUri,\n formatSignatureParams,\n getHeaderValue,\n type RequestLike,\n type ResponseLike,\n type SignatureParams,\n} from './canonicalize';\nexport { computeContentDigest, contentDigestMatches, parseContentDigest } from './content-digest';\nexport {\n requestContextFromExpress,\n requestContextFromFetch,\n requestContextFromLambda,\n type ExpressRequestLike,\n type FetchRequestLike,\n type LambdaRequestEvent,\n type RequestContextFromExpressOptions,\n type RequestContextFromLambdaOptions,\n} from './request-context';\nexport {\n finalizeRequestSignature,\n finalizeResponseSignature,\n prepareRequestSignature,\n prepareResponseSignature,\n prepareWebhookSignature,\n signRequest,\n signResponse,\n signWebhook,\n type PreparedRequestSignature,\n type PreparedResponseSignature,\n type SignatureIdentity,\n type SignedRequest,\n type SignedResponse,\n type SignerKey,\n type SignRequestOptions,\n type SignResponseOptions,\n type SignWebhookOptions,\n} from './signer';\nexport { signRequestAsync, signResponseAsync, signWebhookAsync } from './signer-async';\nexport { derEcdsaToP1363 } from './ecdsa-encoding';\nexport { WEBHOOK_MANDATORY_COMPONENTS, WEBHOOK_SIGNING_TAG } from './webhook-verifier';\nexport { createSigningFetch, type CoverContentDigestPredicate, type SigningFetchOptions } from './fetch';\nexport { createSigningFetchAsync } from './fetch-async';\nexport type { SigningProvider } from './provider';\nexport {\n RequestSignatureError,\n type RequestSignatureErrorCode,\n ResponseSignatureError,\n type ResponseSignatureErrorCode,\n SigningProviderAlgorithmMismatchError,\n type SigningProviderErrorCode,\n WebhookSignatureError,\n type WebhookSignatureErrorCode,\n} from './errors';\nexport {\n ALLOWED_ALGS,\n CLOCK_SKEW_TOLERANCE_SECONDS,\n MANDATORY_COMPONENTS,\n MAX_SIGNATURE_WINDOW_SECONDS,\n REQUEST_SIGNING_TAG,\n RESPONSE_MANDATORY_COMPONENTS,\n RESPONSE_SIGNING_TAG,\n type AdcpJsonWebKey,\n type AdcpSignAlg,\n type ContentDigestPolicy,\n type VerifierCapability,\n} from './types';\nexport {\n CapabilityCache,\n buildCapabilityCacheKey,\n defaultCapabilityCache,\n type CachedCapability,\n type CapabilityCacheOptions,\n} from './capability-cache';\nexport {\n buildAgentSigningFetch,\n createAgentSignedFetch,\n extractAdcpOperation,\n isInlineSigningConfig,\n isProviderSigningConfig,\n resolveCoverContentDigest,\n shouldSignOperation,\n toSignerKey,\n type BuildAgentSigningFetchOptions,\n type CreateAgentSignedFetchOptions,\n} from './agent-fetch';\nexport {\n buildAgentSigningContext,\n signingContextStorage,\n type AgentSigningContext,\n type AgentSigningIdentitySnapshot,\n} from './agent-context';\nexport { ensureCapabilityLoaded, CAPABILITY_OP } from './capability-priming';\nexport { pemToAdcpJwk, type AdcpUse, type PemToAdcpJwkOptions } from './jwks-helpers';\n"],"mappings":"AAQA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP,SAAS,sBAAsB,sBAAsB,0BAA0B;AAC/E;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAUK;AACP,SAAS,kBAAkB,mBAAmB,wBAAwB;AACtE,SAAS,uBAAuB;AAChC,SAAS,8BAA8B,2BAA2B;AAClE,SAAS,0BAAsF;AAC/F,SAAS,+BAA+B;AAExC;AAAA,EACE;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP,SAAS,wBAAwB,qBAAqB;AACtD,SAAS,oBAA4D;","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { createHash, timingSafeEqual } from "crypto";
8
2
  import { parseDictionary } from "structured-headers";
9
3
  const SHA256_MEMBER_RE = /(?:^|[,\s])sha-256=:([A-Za-z0-9+/_-]+={0,2}):/;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/content-digest.ts"],"sourcesContent":["import { createHash, timingSafeEqual } from 'crypto';\nimport { parseDictionary } from 'structured-headers';\n\nconst SHA256_MEMBER_RE = /(?:^|[,\\s])sha-256=:([A-Za-z0-9+/_-]+={0,2}):/;\n\nexport function computeContentDigest(body: string | Uint8Array): string {\n const buf = toBuffer(body);\n const hash = createHash('sha256').update(buf).digest('base64');\n return `sha-256=:${hash}:`;\n}\n\n/**\n * Extract the `sha-256` member from an RFC 9530 Content-Digest header. The\n * header is an RFC 8941 Dictionary and MAY list multiple algorithms; we look\n * up the `sha-256` member without requiring any particular position.\n */\nexport function parseContentDigest(header: string): Buffer | null {\n try {\n const dict = parseDictionary(header);\n const entry = dict.get('sha-256');\n if (entry && entry[0] instanceof ArrayBuffer) return Buffer.from(entry[0]);\n } catch {\n // Fall through: a malformed filler member (e.g. truncated sha-512) should\n // not mask the sha-256 entry we actually verify against.\n }\n const m = header.match(SHA256_MEMBER_RE);\n return m && m[1] ? Buffer.from(m[1], 'base64') : null;\n}\n\nexport function contentDigestMatches(header: string, body: string | Uint8Array): boolean {\n const expected = parseContentDigest(header);\n if (!expected) return false;\n const buf = toBuffer(body);\n const actual = createHash('sha256').update(buf).digest();\n if (expected.length !== actual.length) return false;\n return timingSafeEqual(expected, actual);\n}\n\nfunction toBuffer(body: string | Uint8Array): Buffer {\n if (typeof body === 'string') return Buffer.from(body, 'utf8');\n return Buffer.from(body.buffer, body.byteOffset, body.byteLength);\n}\n"],"mappings":";;;;;;AAAA,SAAS,YAAY,uBAAuB;AAC5C,SAAS,uBAAuB;AAEhC,MAAM,mBAAmB;AAElB,SAAS,qBAAqB,MAAmC;AACtE,QAAM,MAAM,SAAS,IAAI;AACzB,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO,QAAQ;AAC7D,SAAO,YAAY,IAAI;AACzB;AAOO,SAAS,mBAAmB,QAA+B;AAChE,MAAI;AACF,UAAM,OAAO,gBAAgB,MAAM;AACnC,UAAM,QAAQ,KAAK,IAAI,SAAS;AAChC,QAAI,SAAS,MAAM,CAAC,aAAa,YAAa,QAAO,OAAO,KAAK,MAAM,CAAC,CAAC;AAAA,EAC3E,QAAQ;AAAA,EAGR;AACA,QAAM,IAAI,OAAO,MAAM,gBAAgB;AACvC,SAAO,KAAK,EAAE,CAAC,IAAI,OAAO,KAAK,EAAE,CAAC,GAAG,QAAQ,IAAI;AACnD;AAEO,SAAS,qBAAqB,QAAgB,MAAoC;AACvF,QAAM,WAAW,mBAAmB,MAAM;AAC1C,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,MAAM,SAAS,IAAI;AACzB,QAAM,SAAS,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO;AACvD,MAAI,SAAS,WAAW,OAAO,OAAQ,QAAO;AAC9C,SAAO,gBAAgB,UAAU,MAAM;AACzC;AAEA,SAAS,SAAS,MAAmC;AACnD,MAAI,OAAO,SAAS,SAAU,QAAO,OAAO,KAAK,MAAM,MAAM;AAC7D,SAAO,OAAO,KAAK,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;AAClE;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/content-digest.ts"],"sourcesContent":["import { createHash, timingSafeEqual } from 'crypto';\nimport { parseDictionary } from 'structured-headers';\n\nconst SHA256_MEMBER_RE = /(?:^|[,\\s])sha-256=:([A-Za-z0-9+/_-]+={0,2}):/;\n\nexport function computeContentDigest(body: string | Uint8Array): string {\n const buf = toBuffer(body);\n const hash = createHash('sha256').update(buf).digest('base64');\n return `sha-256=:${hash}:`;\n}\n\n/**\n * Extract the `sha-256` member from an RFC 9530 Content-Digest header. The\n * header is an RFC 8941 Dictionary and MAY list multiple algorithms; we look\n * up the `sha-256` member without requiring any particular position.\n */\nexport function parseContentDigest(header: string): Buffer | null {\n try {\n const dict = parseDictionary(header);\n const entry = dict.get('sha-256');\n if (entry && entry[0] instanceof ArrayBuffer) return Buffer.from(entry[0]);\n } catch {\n // Fall through: a malformed filler member (e.g. truncated sha-512) should\n // not mask the sha-256 entry we actually verify against.\n }\n const m = header.match(SHA256_MEMBER_RE);\n return m && m[1] ? Buffer.from(m[1], 'base64') : null;\n}\n\nexport function contentDigestMatches(header: string, body: string | Uint8Array): boolean {\n const expected = parseContentDigest(header);\n if (!expected) return false;\n const buf = toBuffer(body);\n const actual = createHash('sha256').update(buf).digest();\n if (expected.length !== actual.length) return false;\n return timingSafeEqual(expected, actual);\n}\n\nfunction toBuffer(body: string | Uint8Array): Buffer {\n if (typeof body === 'string') return Buffer.from(body, 'utf8');\n return Buffer.from(body.buffer, body.byteOffset, body.byteLength);\n}\n"],"mappings":"AAAA,SAAS,YAAY,uBAAuB;AAC5C,SAAS,uBAAuB;AAEhC,MAAM,mBAAmB;AAElB,SAAS,qBAAqB,MAAmC;AACtE,QAAM,MAAM,SAAS,IAAI;AACzB,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO,QAAQ;AAC7D,SAAO,YAAY,IAAI;AACzB;AAOO,SAAS,mBAAmB,QAA+B;AAChE,MAAI;AACF,UAAM,OAAO,gBAAgB,MAAM;AACnC,UAAM,QAAQ,KAAK,IAAI,SAAS;AAChC,QAAI,SAAS,MAAM,CAAC,aAAa,YAAa,QAAO,OAAO,KAAK,MAAM,CAAC,CAAC;AAAA,EAC3E,QAAQ;AAAA,EAGR;AACA,QAAM,IAAI,OAAO,MAAM,gBAAgB;AACvC,SAAO,KAAK,EAAE,CAAC,IAAI,OAAO,KAAK,EAAE,CAAC,GAAG,QAAQ,IAAI;AACnD;AAEO,SAAS,qBAAqB,QAAgB,MAAoC;AACvF,QAAM,WAAW,mBAAmB,MAAM;AAC1C,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,MAAM,SAAS,IAAI;AACzB,QAAM,SAAS,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO;AACvD,MAAI,SAAS,WAAW,OAAO,OAAQ,QAAO;AAC9C,SAAO,gBAAgB,UAAU,MAAM;AACzC;AAEA,SAAS,SAAS,MAAmC;AACnD,MAAI,OAAO,SAAS,SAAU,QAAO,OAAO,KAAK,MAAM,MAAM;AAC7D,SAAO,OAAO,KAAK,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;AAClE;","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { createPublicKey, verify as nodeVerify } from "crypto";
8
2
  import { RequestSignatureError } from "./errors.mjs";
9
3
  function jwkToPublicKey(jwk) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/crypto.ts"],"sourcesContent":["import { createPublicKey, verify as nodeVerify, type JsonWebKey, type KeyObject } from 'crypto';\nimport { RequestSignatureError } from './errors';\nimport type { AdcpJsonWebKey } from './types';\n\nexport function jwkToPublicKey(jwk: AdcpJsonWebKey): KeyObject {\n const publicJwk: Record<string, unknown> = { ...jwk };\n delete publicJwk._private_d_for_test_only;\n delete publicJwk.d;\n try {\n return createPublicKey({ key: publicJwk as JsonWebKey, format: 'jwk' });\n } catch (err) {\n throw new RequestSignatureError(\n 'request_signature_key_unknown',\n 7,\n `JWK for keyid \"${(jwk.kid as string) ?? '<unknown>'}\" is malformed`,\n err\n );\n }\n}\n\nexport function verifySignature(alg: string, publicKey: KeyObject, data: Uint8Array, signature: Uint8Array): boolean {\n try {\n if (alg === 'ed25519') {\n return nodeVerify(null, data, publicKey, signature);\n }\n if (alg === 'ecdsa-p256-sha256') {\n return nodeVerify('sha256', data, { key: publicKey, dsaEncoding: 'ieee-p1363' }, signature);\n }\n return false;\n } catch {\n // Malformed signature bytes, mismatched key/alg, etc. — map to a caller-\n // observable verify failure rather than letting an opaque crypto Error\n // escape the 12-step pipeline.\n return false;\n }\n}\n"],"mappings":";;;;;;AAAA,SAAS,iBAAiB,UAAU,kBAAmD;AACvF,SAAS,6BAA6B;AAG/B,SAAS,eAAe,KAAgC;AAC7D,QAAM,YAAqC,EAAE,GAAG,IAAI;AACpD,SAAO,UAAU;AACjB,SAAO,UAAU;AACjB,MAAI;AACF,WAAO,gBAAgB,EAAE,KAAK,WAAyB,QAAQ,MAAM,CAAC;AAAA,EACxE,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA,kBAAmB,IAAI,OAAkB,WAAW;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,gBAAgB,KAAa,WAAsB,MAAkB,WAAgC;AACnH,MAAI;AACF,QAAI,QAAQ,WAAW;AACrB,aAAO,WAAW,MAAM,MAAM,WAAW,SAAS;AAAA,IACpD;AACA,QAAI,QAAQ,qBAAqB;AAC/B,aAAO,WAAW,UAAU,MAAM,EAAE,KAAK,WAAW,aAAa,aAAa,GAAG,SAAS;AAAA,IAC5F;AACA,WAAO;AAAA,EACT,QAAQ;AAIN,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/crypto.ts"],"sourcesContent":["import { createPublicKey, verify as nodeVerify, type JsonWebKey, type KeyObject } from 'crypto';\nimport { RequestSignatureError } from './errors';\nimport type { AdcpJsonWebKey } from './types';\n\nexport function jwkToPublicKey(jwk: AdcpJsonWebKey): KeyObject {\n const publicJwk: Record<string, unknown> = { ...jwk };\n delete publicJwk._private_d_for_test_only;\n delete publicJwk.d;\n try {\n return createPublicKey({ key: publicJwk as JsonWebKey, format: 'jwk' });\n } catch (err) {\n throw new RequestSignatureError(\n 'request_signature_key_unknown',\n 7,\n `JWK for keyid \"${(jwk.kid as string) ?? '<unknown>'}\" is malformed`,\n err\n );\n }\n}\n\nexport function verifySignature(alg: string, publicKey: KeyObject, data: Uint8Array, signature: Uint8Array): boolean {\n try {\n if (alg === 'ed25519') {\n return nodeVerify(null, data, publicKey, signature);\n }\n if (alg === 'ecdsa-p256-sha256') {\n return nodeVerify('sha256', data, { key: publicKey, dsaEncoding: 'ieee-p1363' }, signature);\n }\n return false;\n } catch {\n // Malformed signature bytes, mismatched key/alg, etc. — map to a caller-\n // observable verify failure rather than letting an opaque crypto Error\n // escape the 12-step pipeline.\n return false;\n }\n}\n"],"mappings":"AAAA,SAAS,iBAAiB,UAAU,kBAAmD;AACvF,SAAS,6BAA6B;AAG/B,SAAS,eAAe,KAAgC;AAC7D,QAAM,YAAqC,EAAE,GAAG,IAAI;AACpD,SAAO,UAAU;AACjB,SAAO,UAAU;AACjB,MAAI;AACF,WAAO,gBAAgB,EAAE,KAAK,WAAyB,QAAQ,MAAM,CAAC;AAAA,EACxE,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA,kBAAmB,IAAI,OAAkB,WAAW;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,gBAAgB,KAAa,WAAsB,MAAkB,WAAgC;AACnH,MAAI;AACF,QAAI,QAAQ,WAAW;AACrB,aAAO,WAAW,MAAM,MAAM,WAAW,SAAS;AAAA,IACpD;AACA,QAAI,QAAQ,qBAAqB;AAC/B,aAAO,WAAW,UAAU,MAAM,EAAE,KAAK,WAAW,aAAa,aAAa,GAAG,SAAS;AAAA,IAC5F;AACA,WAAO;AAAA,EACT,QAAQ;AAIN,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  function derEcdsaToP1363(der, componentLen) {
8
2
  const readByte = (offset) => {
9
3
  const v = der[offset];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/ecdsa-encoding.ts"],"sourcesContent":["/**\n * Convert a DER-encoded ECDSA signature into the IEEE P1363 (`r‖s`) wire\n * format AdCP and RFC 9421 §3.3.1 require.\n *\n * Most KMS providers (GCP KMS `asymmetricSign`, AWS KMS `Sign` for ECDSA,\n * Azure Key Vault) return DER-encoded ECDSA signatures. The Node `crypto`\n * signer used by the in-memory path produces P1363 directly via\n * `dsaEncoding: 'ieee-p1363'`. KMS adapters need this helper to normalize\n * to the wire format peers expect.\n *\n * `componentLen` is the curve's coordinate width in bytes — 32 for P-256.\n *\n * Each component is left-padded to `componentLen` bytes; DER's leading-zero\n * padding (which exists to keep ASN.1 INTEGER positive) is stripped.\n *\n * Throws if the DER structure is malformed or a component exceeds the\n * declared component length.\n */\nexport function derEcdsaToP1363(der: Uint8Array, componentLen: number): Uint8Array {\n const readByte = (offset: number): number => {\n const v = der[offset];\n if (v === undefined) {\n throw new Error(`Malformed DER ECDSA signature: unexpected end of input at offset ${offset}.`);\n }\n return v;\n };\n\n if (der.length < 8 || readByte(0) !== 0x30) {\n throw new Error('Malformed DER ECDSA signature: missing SEQUENCE tag.');\n }\n let cursor = 2;\n const lengthByte = readByte(1);\n // SEQUENCE total-content length, used to validate the parsed contents\n // don't claim more bytes than the buffer holds.\n let sequenceContentLen: number;\n // P-256 ECDSA signatures are always short-form length encoded (<= 72 bytes\n // including header), so production callers never hit the long-form branch.\n // We still parse long-form defensively but reject anything that would put\n // cursor past the buffer.\n if ((lengthByte & 0x80) !== 0) {\n const skip = lengthByte & 0x7f;\n if (skip === 0 || skip > 4) {\n throw new Error('Malformed DER ECDSA signature: invalid long-form length.');\n }\n sequenceContentLen = 0;\n for (let i = 0; i < skip; i++) {\n sequenceContentLen = (sequenceContentLen << 8) | readByte(2 + i);\n }\n cursor = 2 + skip;\n if (cursor >= der.length) {\n throw new Error('Malformed DER ECDSA signature: long-form length runs past buffer.');\n }\n } else {\n sequenceContentLen = lengthByte;\n }\n if (cursor + sequenceContentLen > der.length) {\n throw new Error('Malformed DER ECDSA signature: SEQUENCE content runs past buffer.');\n }\n if (readByte(cursor) !== 0x02) {\n throw new Error('Malformed DER ECDSA signature: missing INTEGER tag for r.');\n }\n const rLen = readByte(cursor + 1);\n if (cursor + 2 + rLen > der.length) {\n throw new Error('Malformed DER ECDSA signature: r INTEGER length runs past buffer.');\n }\n let r = der.subarray(cursor + 2, cursor + 2 + rLen);\n cursor = cursor + 2 + rLen;\n if (readByte(cursor) !== 0x02) {\n throw new Error('Malformed DER ECDSA signature: missing INTEGER tag for s.');\n }\n const sLen = readByte(cursor + 1);\n if (cursor + 2 + sLen > der.length) {\n throw new Error('Malformed DER ECDSA signature: s INTEGER length runs past buffer.');\n }\n let s = der.subarray(cursor + 2, cursor + 2 + sLen);\n\n if (r.length > componentLen && r[0] === 0x00) r = r.subarray(1);\n if (s.length > componentLen && s[0] === 0x00) s = s.subarray(1);\n\n if (r.length > componentLen || s.length > componentLen) {\n throw new Error(`DER ECDSA component longer than expected ${componentLen}-byte wire format.`);\n }\n const out = new Uint8Array(componentLen * 2);\n out.set(r, componentLen - r.length);\n out.set(s, componentLen * 2 - s.length);\n return out;\n}\n"],"mappings":";;;;;;AAkBO,SAAS,gBAAgB,KAAiB,cAAkC;AACjF,QAAM,WAAW,CAAC,WAA2B;AAC3C,UAAM,IAAI,IAAI,MAAM;AACpB,QAAI,MAAM,QAAW;AACnB,YAAM,IAAI,MAAM,oEAAoE,MAAM,GAAG;AAAA,IAC/F;AACA,WAAO;AAAA,EACT;AAEA,MAAI,IAAI,SAAS,KAAK,SAAS,CAAC,MAAM,IAAM;AAC1C,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,MAAI,SAAS;AACb,QAAM,aAAa,SAAS,CAAC;AAG7B,MAAI;AAKJ,OAAK,aAAa,SAAU,GAAG;AAC7B,UAAM,OAAO,aAAa;AAC1B,QAAI,SAAS,KAAK,OAAO,GAAG;AAC1B,YAAM,IAAI,MAAM,0DAA0D;AAAA,IAC5E;AACA,yBAAqB;AACrB,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,2BAAsB,sBAAsB,IAAK,SAAS,IAAI,CAAC;AAAA,IACjE;AACA,aAAS,IAAI;AACb,QAAI,UAAU,IAAI,QAAQ;AACxB,YAAM,IAAI,MAAM,mEAAmE;AAAA,IACrF;AAAA,EACF,OAAO;AACL,yBAAqB;AAAA,EACvB;AACA,MAAI,SAAS,qBAAqB,IAAI,QAAQ;AAC5C,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AACA,MAAI,SAAS,MAAM,MAAM,GAAM;AAC7B,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,QAAM,OAAO,SAAS,SAAS,CAAC;AAChC,MAAI,SAAS,IAAI,OAAO,IAAI,QAAQ;AAClC,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AACA,MAAI,IAAI,IAAI,SAAS,SAAS,GAAG,SAAS,IAAI,IAAI;AAClD,WAAS,SAAS,IAAI;AACtB,MAAI,SAAS,MAAM,MAAM,GAAM;AAC7B,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,QAAM,OAAO,SAAS,SAAS,CAAC;AAChC,MAAI,SAAS,IAAI,OAAO,IAAI,QAAQ;AAClC,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AACA,MAAI,IAAI,IAAI,SAAS,SAAS,GAAG,SAAS,IAAI,IAAI;AAElD,MAAI,EAAE,SAAS,gBAAgB,EAAE,CAAC,MAAM,EAAM,KAAI,EAAE,SAAS,CAAC;AAC9D,MAAI,EAAE,SAAS,gBAAgB,EAAE,CAAC,MAAM,EAAM,KAAI,EAAE,SAAS,CAAC;AAE9D,MAAI,EAAE,SAAS,gBAAgB,EAAE,SAAS,cAAc;AACtD,UAAM,IAAI,MAAM,4CAA4C,YAAY,oBAAoB;AAAA,EAC9F;AACA,QAAM,MAAM,IAAI,WAAW,eAAe,CAAC;AAC3C,MAAI,IAAI,GAAG,eAAe,EAAE,MAAM;AAClC,MAAI,IAAI,GAAG,eAAe,IAAI,EAAE,MAAM;AACtC,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/ecdsa-encoding.ts"],"sourcesContent":["/**\n * Convert a DER-encoded ECDSA signature into the IEEE P1363 (`r‖s`) wire\n * format AdCP and RFC 9421 §3.3.1 require.\n *\n * Most KMS providers (GCP KMS `asymmetricSign`, AWS KMS `Sign` for ECDSA,\n * Azure Key Vault) return DER-encoded ECDSA signatures. The Node `crypto`\n * signer used by the in-memory path produces P1363 directly via\n * `dsaEncoding: 'ieee-p1363'`. KMS adapters need this helper to normalize\n * to the wire format peers expect.\n *\n * `componentLen` is the curve's coordinate width in bytes — 32 for P-256.\n *\n * Each component is left-padded to `componentLen` bytes; DER's leading-zero\n * padding (which exists to keep ASN.1 INTEGER positive) is stripped.\n *\n * Throws if the DER structure is malformed or a component exceeds the\n * declared component length.\n */\nexport function derEcdsaToP1363(der: Uint8Array, componentLen: number): Uint8Array {\n const readByte = (offset: number): number => {\n const v = der[offset];\n if (v === undefined) {\n throw new Error(`Malformed DER ECDSA signature: unexpected end of input at offset ${offset}.`);\n }\n return v;\n };\n\n if (der.length < 8 || readByte(0) !== 0x30) {\n throw new Error('Malformed DER ECDSA signature: missing SEQUENCE tag.');\n }\n let cursor = 2;\n const lengthByte = readByte(1);\n // SEQUENCE total-content length, used to validate the parsed contents\n // don't claim more bytes than the buffer holds.\n let sequenceContentLen: number;\n // P-256 ECDSA signatures are always short-form length encoded (<= 72 bytes\n // including header), so production callers never hit the long-form branch.\n // We still parse long-form defensively but reject anything that would put\n // cursor past the buffer.\n if ((lengthByte & 0x80) !== 0) {\n const skip = lengthByte & 0x7f;\n if (skip === 0 || skip > 4) {\n throw new Error('Malformed DER ECDSA signature: invalid long-form length.');\n }\n sequenceContentLen = 0;\n for (let i = 0; i < skip; i++) {\n sequenceContentLen = (sequenceContentLen << 8) | readByte(2 + i);\n }\n cursor = 2 + skip;\n if (cursor >= der.length) {\n throw new Error('Malformed DER ECDSA signature: long-form length runs past buffer.');\n }\n } else {\n sequenceContentLen = lengthByte;\n }\n if (cursor + sequenceContentLen > der.length) {\n throw new Error('Malformed DER ECDSA signature: SEQUENCE content runs past buffer.');\n }\n if (readByte(cursor) !== 0x02) {\n throw new Error('Malformed DER ECDSA signature: missing INTEGER tag for r.');\n }\n const rLen = readByte(cursor + 1);\n if (cursor + 2 + rLen > der.length) {\n throw new Error('Malformed DER ECDSA signature: r INTEGER length runs past buffer.');\n }\n let r = der.subarray(cursor + 2, cursor + 2 + rLen);\n cursor = cursor + 2 + rLen;\n if (readByte(cursor) !== 0x02) {\n throw new Error('Malformed DER ECDSA signature: missing INTEGER tag for s.');\n }\n const sLen = readByte(cursor + 1);\n if (cursor + 2 + sLen > der.length) {\n throw new Error('Malformed DER ECDSA signature: s INTEGER length runs past buffer.');\n }\n let s = der.subarray(cursor + 2, cursor + 2 + sLen);\n\n if (r.length > componentLen && r[0] === 0x00) r = r.subarray(1);\n if (s.length > componentLen && s[0] === 0x00) s = s.subarray(1);\n\n if (r.length > componentLen || s.length > componentLen) {\n throw new Error(`DER ECDSA component longer than expected ${componentLen}-byte wire format.`);\n }\n const out = new Uint8Array(componentLen * 2);\n out.set(r, componentLen - r.length);\n out.set(s, componentLen * 2 - s.length);\n return out;\n}\n"],"mappings":"AAkBO,SAAS,gBAAgB,KAAiB,cAAkC;AACjF,QAAM,WAAW,CAAC,WAA2B;AAC3C,UAAM,IAAI,IAAI,MAAM;AACpB,QAAI,MAAM,QAAW;AACnB,YAAM,IAAI,MAAM,oEAAoE,MAAM,GAAG;AAAA,IAC/F;AACA,WAAO;AAAA,EACT;AAEA,MAAI,IAAI,SAAS,KAAK,SAAS,CAAC,MAAM,IAAM;AAC1C,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,MAAI,SAAS;AACb,QAAM,aAAa,SAAS,CAAC;AAG7B,MAAI;AAKJ,OAAK,aAAa,SAAU,GAAG;AAC7B,UAAM,OAAO,aAAa;AAC1B,QAAI,SAAS,KAAK,OAAO,GAAG;AAC1B,YAAM,IAAI,MAAM,0DAA0D;AAAA,IAC5E;AACA,yBAAqB;AACrB,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,2BAAsB,sBAAsB,IAAK,SAAS,IAAI,CAAC;AAAA,IACjE;AACA,aAAS,IAAI;AACb,QAAI,UAAU,IAAI,QAAQ;AACxB,YAAM,IAAI,MAAM,mEAAmE;AAAA,IACrF;AAAA,EACF,OAAO;AACL,yBAAqB;AAAA,EACvB;AACA,MAAI,SAAS,qBAAqB,IAAI,QAAQ;AAC5C,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AACA,MAAI,SAAS,MAAM,MAAM,GAAM;AAC7B,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,QAAM,OAAO,SAAS,SAAS,CAAC;AAChC,MAAI,SAAS,IAAI,OAAO,IAAI,QAAQ;AAClC,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AACA,MAAI,IAAI,IAAI,SAAS,SAAS,GAAG,SAAS,IAAI,IAAI;AAClD,WAAS,SAAS,IAAI;AACtB,MAAI,SAAS,MAAM,MAAM,GAAM;AAC7B,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,QAAM,OAAO,SAAS,SAAS,CAAC;AAChC,MAAI,SAAS,IAAI,OAAO,IAAI,QAAQ;AAClC,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AACA,MAAI,IAAI,IAAI,SAAS,SAAS,GAAG,SAAS,IAAI,IAAI;AAElD,MAAI,EAAE,SAAS,gBAAgB,EAAE,CAAC,MAAM,EAAM,KAAI,EAAE,SAAS,CAAC;AAC9D,MAAI,EAAE,SAAS,gBAAgB,EAAE,CAAC,MAAM,EAAM,KAAI,EAAE,SAAS,CAAC;AAE9D,MAAI,EAAE,SAAS,gBAAgB,EAAE,SAAS,cAAc;AACtD,UAAM,IAAI,MAAM,4CAA4C,YAAY,oBAAoB;AAAA,EAC9F;AACA,QAAM,MAAM,IAAI,WAAW,eAAe,CAAC;AAC3C,MAAI,IAAI,GAAG,eAAe,EAAE,MAAM;AAClC,MAAI,IAAI,GAAG,eAAe,IAAI,EAAE,MAAM;AACtC,SAAO;AACT;","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { ADCPError } from "../errors/index.mjs";
8
2
  class RequestSignatureError extends ADCPError {
9
3
  code;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/errors.ts"],"sourcesContent":["import { ADCPError } from '../errors';\n\nexport type RequestSignatureErrorCode =\n | 'request_signature_required'\n | 'request_signature_header_malformed'\n | 'request_signature_params_incomplete'\n | 'request_signature_tag_invalid'\n | 'request_signature_alg_not_allowed'\n | 'request_signature_window_invalid'\n | 'request_signature_components_incomplete'\n | 'request_signature_components_unexpected'\n | 'request_signature_key_unknown'\n | 'request_signature_key_purpose_invalid'\n | 'request_signature_key_revoked'\n | 'request_signature_invalid'\n | 'request_signature_digest_mismatch'\n | 'request_signature_replayed'\n | 'request_signature_rate_abuse'\n | 'request_signature_revocation_stale';\n\nexport class RequestSignatureError extends ADCPError {\n readonly code: RequestSignatureErrorCode;\n readonly failedStep: number;\n\n constructor(code: RequestSignatureErrorCode, failedStep: number, message: string, details?: unknown) {\n super(message, details);\n this.code = code;\n this.failedStep = failedStep;\n }\n}\n\n/**\n * Error codes surfaced by the RFC 9421 webhook-signing verifier. Maps onto\n * the `webhook_signature_*` codes enumerated by the webhook-emission\n * storyboard (adcontextprotocol/adcp#2431) with matching semantics.\n */\n/**\n * Error taxonomy per the merged spec in `security.mdx#webhook-callbacks`\n * and the conformance vectors at `test-vectors/webhook-signing/`. The spec\n * folds every window failure (expired, negative window, over-long window,\n * created-in-future) into a single `webhook_signature_window_invalid` code —\n * no distinct `_expired`.\n */\nexport type WebhookSignatureErrorCode =\n | 'webhook_signature_header_malformed'\n | 'webhook_signature_params_incomplete'\n | 'webhook_signature_tag_invalid'\n | 'webhook_signature_alg_not_allowed'\n | 'webhook_signature_window_invalid'\n | 'webhook_signature_components_incomplete'\n // `@target-uri` covered-component value failed syntactic validation (non-\n // parseable URL, non-https scheme, userinfo present, fragment present).\n // Distinct from `header_malformed`, which flags the `Signature` /\n // `Signature-Input` headers themselves; this flags the covered URI.\n | 'webhook_target_uri_malformed'\n | 'webhook_signature_key_unknown'\n // Every webhook key-purpose failure: absent `adcp_use`, a missing `verify`\n // key_op, or an `adcp_use` outside the accepted set. Webhooks are signed\n // with a `request-signing` key (the deprecated `webhook-signing` is also\n // accepted for backward compatibility); any other purpose\n // (`response-signing`, `governance-signing`) is rejected with this code.\n | 'webhook_signature_key_purpose_invalid'\n // The buyer's registered auth mode does not match the signing mode on the\n // received webhook (HMAC-vs-9421 selector mismatch — see the spec's\n // downgrade-resistance rules). This is NOT a key-purpose failure; reusing a\n // request-signing key for webhooks is allowed and verifies cleanly.\n | 'webhook_mode_mismatch'\n | 'webhook_signature_key_revoked'\n | 'webhook_signature_revocation_stale'\n | 'webhook_signature_rate_abuse'\n | 'webhook_signature_invalid'\n | 'webhook_signature_digest_mismatch'\n | 'webhook_signature_replayed';\n\nexport class WebhookSignatureError extends ADCPError {\n readonly code: WebhookSignatureErrorCode;\n readonly failedStep: number;\n\n constructor(code: WebhookSignatureErrorCode, failedStep: number, message: string, details?: unknown) {\n super(message, details);\n this.code = code;\n this.failedStep = failedStep;\n }\n}\n\nexport type ResponseSignatureErrorCode = 'response_signature_key_purpose_invalid';\n\nexport class ResponseSignatureError extends ADCPError {\n readonly code: ResponseSignatureErrorCode;\n readonly failedStep: number;\n\n constructor(code: ResponseSignatureErrorCode, failedStep: number, message: string, details?: unknown) {\n super(message, details);\n this.code = code;\n this.failedStep = failedStep;\n }\n}\n\n/**\n * SDK-side error codes for the `SigningProvider` integration path. Distinct\n * namespace from `RequestSignatureErrorCode` / `WebhookSignatureErrorCode`\n * because these surface during adapter setup, not during wire-level\n * signature verification.\n */\nexport type SigningProviderErrorCode = 'signing_provider_algorithm_mismatch';\n\n/**\n * Adapter-side error thrown when a `SigningProvider`'s declared `algorithm`\n * doesn't match the algorithm of the underlying key material.\n *\n * KMS providers should detect this during construction (one-shot\n * `getPublicKey` / `describe-key` call) so misconfigurations fail before\n * the first signed request rather than producing signatures verifiers\n * reject downstream with the generic `request_signature_invalid` code.\n */\nexport class SigningProviderAlgorithmMismatchError extends ADCPError {\n readonly code: SigningProviderErrorCode = 'signing_provider_algorithm_mismatch';\n readonly expected: string;\n readonly actual: string;\n readonly providerKid: string;\n\n constructor(expected: string, actual: string, providerKid: string) {\n super(\n `SigningProvider declared algorithm '${expected}' but underlying key is '${actual}' (kid='${providerKid}'). ` +\n `Reconfigure the adapter to match the key, or rotate to a key whose algorithm matches the declared one.`\n );\n this.expected = expected;\n this.actual = actual;\n this.providerKid = providerKid;\n }\n}\n"],"mappings":";;;;;;AAAA,SAAS,iBAAiB;AAoBnB,MAAM,8BAA8B,UAAU;AAAA,EAC1C;AAAA,EACA;AAAA,EAET,YAAY,MAAiC,YAAoB,SAAiB,SAAmB;AACnG,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AA6CO,MAAM,8BAA8B,UAAU;AAAA,EAC1C;AAAA,EACA;AAAA,EAET,YAAY,MAAiC,YAAoB,SAAiB,SAAmB;AACnG,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AAIO,MAAM,+BAA+B,UAAU;AAAA,EAC3C;AAAA,EACA;AAAA,EAET,YAAY,MAAkC,YAAoB,SAAiB,SAAmB;AACpG,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AAmBO,MAAM,8CAA8C,UAAU;AAAA,EAC1D,OAAiC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,UAAkB,QAAgB,aAAqB;AACjE;AAAA,MACE,uCAAuC,QAAQ,4BAA4B,MAAM,WAAW,WAAW;AAAA,IAEzG;AACA,SAAK,WAAW;AAChB,SAAK,SAAS;AACd,SAAK,cAAc;AAAA,EACrB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/errors.ts"],"sourcesContent":["import { ADCPError } from '../errors';\n\nexport type RequestSignatureErrorCode =\n | 'request_signature_required'\n | 'request_signature_header_malformed'\n | 'request_signature_params_incomplete'\n | 'request_signature_tag_invalid'\n | 'request_signature_alg_not_allowed'\n | 'request_signature_window_invalid'\n | 'request_signature_components_incomplete'\n | 'request_signature_components_unexpected'\n | 'request_signature_key_unknown'\n | 'request_signature_key_purpose_invalid'\n | 'request_signature_key_revoked'\n | 'request_signature_invalid'\n | 'request_signature_digest_mismatch'\n | 'request_signature_replayed'\n | 'request_signature_rate_abuse'\n | 'request_signature_revocation_stale';\n\nexport class RequestSignatureError extends ADCPError {\n readonly code: RequestSignatureErrorCode;\n readonly failedStep: number;\n\n constructor(code: RequestSignatureErrorCode, failedStep: number, message: string, details?: unknown) {\n super(message, details);\n this.code = code;\n this.failedStep = failedStep;\n }\n}\n\n/**\n * Error codes surfaced by the RFC 9421 webhook-signing verifier. Maps onto\n * the `webhook_signature_*` codes enumerated by the webhook-emission\n * storyboard (adcontextprotocol/adcp#2431) with matching semantics.\n */\n/**\n * Error taxonomy per the merged spec in `security.mdx#webhook-callbacks`\n * and the conformance vectors at `test-vectors/webhook-signing/`. The spec\n * folds every window failure (expired, negative window, over-long window,\n * created-in-future) into a single `webhook_signature_window_invalid` code —\n * no distinct `_expired`.\n */\nexport type WebhookSignatureErrorCode =\n | 'webhook_signature_header_malformed'\n | 'webhook_signature_params_incomplete'\n | 'webhook_signature_tag_invalid'\n | 'webhook_signature_alg_not_allowed'\n | 'webhook_signature_window_invalid'\n | 'webhook_signature_components_incomplete'\n // `@target-uri` covered-component value failed syntactic validation (non-\n // parseable URL, non-https scheme, userinfo present, fragment present).\n // Distinct from `header_malformed`, which flags the `Signature` /\n // `Signature-Input` headers themselves; this flags the covered URI.\n | 'webhook_target_uri_malformed'\n | 'webhook_signature_key_unknown'\n // Every webhook key-purpose failure: absent `adcp_use`, a missing `verify`\n // key_op, or an `adcp_use` outside the accepted set. Webhooks are signed\n // with a `request-signing` key (the deprecated `webhook-signing` is also\n // accepted for backward compatibility); any other purpose\n // (`response-signing`, `governance-signing`) is rejected with this code.\n | 'webhook_signature_key_purpose_invalid'\n // The buyer's registered auth mode does not match the signing mode on the\n // received webhook (HMAC-vs-9421 selector mismatch — see the spec's\n // downgrade-resistance rules). This is NOT a key-purpose failure; reusing a\n // request-signing key for webhooks is allowed and verifies cleanly.\n | 'webhook_mode_mismatch'\n | 'webhook_signature_key_revoked'\n | 'webhook_signature_revocation_stale'\n | 'webhook_signature_rate_abuse'\n | 'webhook_signature_invalid'\n | 'webhook_signature_digest_mismatch'\n | 'webhook_signature_replayed';\n\nexport class WebhookSignatureError extends ADCPError {\n readonly code: WebhookSignatureErrorCode;\n readonly failedStep: number;\n\n constructor(code: WebhookSignatureErrorCode, failedStep: number, message: string, details?: unknown) {\n super(message, details);\n this.code = code;\n this.failedStep = failedStep;\n }\n}\n\nexport type ResponseSignatureErrorCode = 'response_signature_key_purpose_invalid';\n\nexport class ResponseSignatureError extends ADCPError {\n readonly code: ResponseSignatureErrorCode;\n readonly failedStep: number;\n\n constructor(code: ResponseSignatureErrorCode, failedStep: number, message: string, details?: unknown) {\n super(message, details);\n this.code = code;\n this.failedStep = failedStep;\n }\n}\n\n/**\n * SDK-side error codes for the `SigningProvider` integration path. Distinct\n * namespace from `RequestSignatureErrorCode` / `WebhookSignatureErrorCode`\n * because these surface during adapter setup, not during wire-level\n * signature verification.\n */\nexport type SigningProviderErrorCode = 'signing_provider_algorithm_mismatch';\n\n/**\n * Adapter-side error thrown when a `SigningProvider`'s declared `algorithm`\n * doesn't match the algorithm of the underlying key material.\n *\n * KMS providers should detect this during construction (one-shot\n * `getPublicKey` / `describe-key` call) so misconfigurations fail before\n * the first signed request rather than producing signatures verifiers\n * reject downstream with the generic `request_signature_invalid` code.\n */\nexport class SigningProviderAlgorithmMismatchError extends ADCPError {\n readonly code: SigningProviderErrorCode = 'signing_provider_algorithm_mismatch';\n readonly expected: string;\n readonly actual: string;\n readonly providerKid: string;\n\n constructor(expected: string, actual: string, providerKid: string) {\n super(\n `SigningProvider declared algorithm '${expected}' but underlying key is '${actual}' (kid='${providerKid}'). ` +\n `Reconfigure the adapter to match the key, or rotate to a key whose algorithm matches the declared one.`\n );\n this.expected = expected;\n this.actual = actual;\n this.providerKid = providerKid;\n }\n}\n"],"mappings":"AAAA,SAAS,iBAAiB;AAoBnB,MAAM,8BAA8B,UAAU;AAAA,EAC1C;AAAA,EACA;AAAA,EAET,YAAY,MAAiC,YAAoB,SAAiB,SAAmB;AACnG,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AA6CO,MAAM,8BAA8B,UAAU;AAAA,EAC1C;AAAA,EACA;AAAA,EAET,YAAY,MAAiC,YAAoB,SAAiB,SAAmB;AACnG,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AAIO,MAAM,+BAA+B,UAAU;AAAA,EAC3C;AAAA,EACA;AAAA,EAET,YAAY,MAAkC,YAAoB,SAAiB,SAAmB;AACpG,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AAmBO,MAAM,8CAA8C,UAAU;AAAA,EAC1D,OAAiC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,UAAkB,QAAgB,aAAqB;AACjE;AAAA,MACE,uCAAuC,QAAQ,4BAA4B,MAAM,WAAW,WAAW;AAAA,IAEzG;AACA,SAAK,WAAW;AAChB,SAAK,SAAS;AACd,SAAK,cAAc;AAAA,EACrB;AACF;","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { signRequestAsync } from "./signer-async.mjs";
8
2
  const SIGNING_RESERVED_HEADERS = /* @__PURE__ */ new Set(["signature", "signature-input", "content-digest"]);
9
3
  function createSigningFetchAsync(upstream, provider, options = {}) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/signing/fetch-async.ts"],"sourcesContent":["import type { CoverContentDigestPredicate, SigningFetchOptions } from './fetch';\nimport type { SigningProvider } from './provider';\nimport type { SignRequestOptions } from './signer';\nimport { signRequestAsync } from './signer-async';\n\ntype FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\n// Mirrors `fetch.ts`'s SIGNING_RESERVED_HEADERS. `authorization` is intentionally\n// NOT in this set — AdCP's RFC 9421 profile does not cover Authorization, so\n// caller-supplied Bearer / RFC 7617 Basic headers pass through unmodified. See\n// `fetch.ts` for the full rationale and the RFC 9421 §7.5.7 caveat about\n// signing over long-lived credentials.\nconst SIGNING_RESERVED_HEADERS = new Set(['signature', 'signature-input', 'content-digest']);\n\n/**\n * Async-signing variant of `createSigningFetch`. Identical request\n * extraction and reserved-header policy; differs only in routing through a\n * {@link SigningProvider}, which may issue a network call to a managed key\n * store on every signed request. Returns the same `FetchLike` shape so the\n * wrapped function is interchangeable with the sync-signed variant from\n * the caller's point of view.\n *\n * The split between {@link createSigningFetch} (sync inner) and this helper\n * is deliberate: hover docs and the function name surface the latency-cost\n * distinction at integration time. Use the sync entry point with an\n * in-memory `SignerKey`; use this one with a KMS-backed `SigningProvider`.\n *\n * Keep in sync with `createSigningFetch` in `./fetch.ts` — reserved-header\n * policy, content-type defaulting, and `Request`-rejection are line-for-line\n * parallel.\n */\nexport function createSigningFetchAsync(\n upstream: FetchLike,\n provider: SigningProvider,\n options: SigningFetchOptions = {}\n): FetchLike {\n return async (input, init) => {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase();\n const shouldSign = options.shouldSign ?? (() => method !== 'GET');\n if (!shouldSign(url, init)) return upstream(input, init);\n\n if (input instanceof Request) {\n throw new TypeError(\n 'createSigningFetchAsync does not accept Request objects (the body would be consumed out from under the signer). Pass a URL string and a separate init.'\n );\n }\n\n const headers = headersToRecord(init?.headers);\n for (const name of Object.keys(headers)) {\n if (SIGNING_RESERVED_HEADERS.has(name.toLowerCase())) {\n delete headers[name];\n }\n }\n const hasContentType = Object.keys(headers).some(k => k.toLowerCase() === 'content-type');\n if (!hasContentType && (init?.body !== undefined || method !== 'GET')) {\n headers['content-type'] = 'application/json';\n }\n const body = bodyToString(init?.body);\n\n const coverContentDigest =\n typeof options.coverContentDigest === 'function'\n ? (options.coverContentDigest as CoverContentDigestPredicate)(url, init)\n : options.coverContentDigest;\n const { coverContentDigest: _omit, ...signerOptionsBase } = options;\n const signerOptions: SignRequestOptions = { ...signerOptionsBase, coverContentDigest };\n\n const signed = await signRequestAsync({ method, url, headers, body }, provider, signerOptions);\n\n const mergedInit: RequestInit = { ...init, method, headers: signed.headers };\n if (body !== undefined && mergedInit.body === undefined) mergedInit.body = body;\n return upstream(url, mergedInit);\n };\n}\n\nfunction headersToRecord(headers: HeadersInit | Headers | undefined): Record<string, string> {\n if (!headers) return {};\n if (headers instanceof Headers) {\n const out: Record<string, string> = {};\n headers.forEach((v, k) => {\n out[k] = v;\n });\n return out;\n }\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers);\n }\n return { ...(headers as Record<string, string>) };\n}\n\nfunction bodyToString(body: RequestInit['body']): string | undefined {\n if (body === undefined || body === null) return undefined;\n if (typeof body === 'string') return body;\n if (body instanceof Uint8Array) return decodeUtf8Strict(body);\n if (body instanceof ArrayBuffer) return decodeUtf8Strict(new Uint8Array(body));\n throw new TypeError(\n 'createSigningFetchAsync requires a string, Uint8Array, or ArrayBuffer body. FormData / Blob / ReadableStream are not supported because the signature must cover the exact wire bytes.'\n );\n}\n\n/**\n * Decode bytes to UTF-8, throwing on invalid sequences. See the matching\n * helper in `./fetch.ts` for the full rationale; both wrappers refuse\n * non-UTF-8 byte bodies so callers don't get silent body corruption.\n */\nfunction decodeUtf8Strict(bytes: Uint8Array): string {\n try {\n return new TextDecoder('utf-8', { fatal: true }).decode(bytes);\n } catch {\n throw new TypeError(\n 'createSigningFetchAsync received a Uint8Array/ArrayBuffer body that is not valid UTF-8. ' +\n 'Pass a string body, ensure the bytes are UTF-8, or sign the request manually with `signRequestAsync` against the exact wire bytes you intend to send.'\n );\n }\n}\n"],"mappings":";;;;;;AAGA,SAAS,wBAAwB;AASjC,MAAM,2BAA2B,oBAAI,IAAI,CAAC,aAAa,mBAAmB,gBAAgB,CAAC;AAmBpF,SAAS,wBACd,UACA,UACA,UAA+B,CAAC,GACrB;AACX,SAAO,OAAO,OAAO,SAAS;AAC5B,UAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,iBAAiB,MAAM,MAAM,SAAS,IAAI,MAAM;AAChG,UAAM,UAAU,MAAM,WAAW,iBAAiB,UAAU,MAAM,SAAS,QAAQ,YAAY;AAC/F,UAAM,aAAa,QAAQ,eAAe,MAAM,WAAW;AAC3D,QAAI,CAAC,WAAW,KAAK,IAAI,EAAG,QAAO,SAAS,OAAO,IAAI;AAEvD,QAAI,iBAAiB,SAAS;AAC5B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,gBAAgB,MAAM,OAAO;AAC7C,eAAW,QAAQ,OAAO,KAAK,OAAO,GAAG;AACvC,UAAI,yBAAyB,IAAI,KAAK,YAAY,CAAC,GAAG;AACpD,eAAO,QAAQ,IAAI;AAAA,MACrB;AAAA,IACF;AACA,UAAM,iBAAiB,OAAO,KAAK,OAAO,EAAE,KAAK,OAAK,EAAE,YAAY,MAAM,cAAc;AACxF,QAAI,CAAC,mBAAmB,MAAM,SAAS,UAAa,WAAW,QAAQ;AACrE,cAAQ,cAAc,IAAI;AAAA,IAC5B;AACA,UAAM,OAAO,aAAa,MAAM,IAAI;AAEpC,UAAM,qBACJ,OAAO,QAAQ,uBAAuB,aACjC,QAAQ,mBAAmD,KAAK,IAAI,IACrE,QAAQ;AACd,UAAM,EAAE,oBAAoB,OAAO,GAAG,kBAAkB,IAAI;AAC5D,UAAM,gBAAoC,EAAE,GAAG,mBAAmB,mBAAmB;AAErF,UAAM,SAAS,MAAM,iBAAiB,EAAE,QAAQ,KAAK,SAAS,KAAK,GAAG,UAAU,aAAa;AAE7F,UAAM,aAA0B,EAAE,GAAG,MAAM,QAAQ,SAAS,OAAO,QAAQ;AAC3E,QAAI,SAAS,UAAa,WAAW,SAAS,OAAW,YAAW,OAAO;AAC3E,WAAO,SAAS,KAAK,UAAU;AAAA,EACjC;AACF;AAEA,SAAS,gBAAgB,SAAoE;AAC3F,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,MAAI,mBAAmB,SAAS;AAC9B,UAAM,MAA8B,CAAC;AACrC,YAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,UAAI,CAAC,IAAI;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,WAAO,OAAO,YAAY,OAAO;AAAA,EACnC;AACA,SAAO,EAAE,GAAI,QAAmC;AAClD;AAEA,SAAS,aAAa,MAA+C;AACnE,MAAI,SAAS,UAAa,SAAS,KAAM,QAAO;AAChD,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,MAAI,gBAAgB,WAAY,QAAO,iBAAiB,IAAI;AAC5D,MAAI,gBAAgB,YAAa,QAAO,iBAAiB,IAAI,WAAW,IAAI,CAAC;AAC7E,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAOA,SAAS,iBAAiB,OAA2B;AACnD,MAAI;AACF,WAAO,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,EAAE,OAAO,KAAK;AAAA,EAC/D,QAAQ;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/signing/fetch-async.ts"],"sourcesContent":["import type { CoverContentDigestPredicate, SigningFetchOptions } from './fetch';\nimport type { SigningProvider } from './provider';\nimport type { SignRequestOptions } from './signer';\nimport { signRequestAsync } from './signer-async';\n\ntype FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\n// Mirrors `fetch.ts`'s SIGNING_RESERVED_HEADERS. `authorization` is intentionally\n// NOT in this set — AdCP's RFC 9421 profile does not cover Authorization, so\n// caller-supplied Bearer / RFC 7617 Basic headers pass through unmodified. See\n// `fetch.ts` for the full rationale and the RFC 9421 §7.5.7 caveat about\n// signing over long-lived credentials.\nconst SIGNING_RESERVED_HEADERS = new Set(['signature', 'signature-input', 'content-digest']);\n\n/**\n * Async-signing variant of `createSigningFetch`. Identical request\n * extraction and reserved-header policy; differs only in routing through a\n * {@link SigningProvider}, which may issue a network call to a managed key\n * store on every signed request. Returns the same `FetchLike` shape so the\n * wrapped function is interchangeable with the sync-signed variant from\n * the caller's point of view.\n *\n * The split between {@link createSigningFetch} (sync inner) and this helper\n * is deliberate: hover docs and the function name surface the latency-cost\n * distinction at integration time. Use the sync entry point with an\n * in-memory `SignerKey`; use this one with a KMS-backed `SigningProvider`.\n *\n * Keep in sync with `createSigningFetch` in `./fetch.ts` — reserved-header\n * policy, content-type defaulting, and `Request`-rejection are line-for-line\n * parallel.\n */\nexport function createSigningFetchAsync(\n upstream: FetchLike,\n provider: SigningProvider,\n options: SigningFetchOptions = {}\n): FetchLike {\n return async (input, init) => {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase();\n const shouldSign = options.shouldSign ?? (() => method !== 'GET');\n if (!shouldSign(url, init)) return upstream(input, init);\n\n if (input instanceof Request) {\n throw new TypeError(\n 'createSigningFetchAsync does not accept Request objects (the body would be consumed out from under the signer). Pass a URL string and a separate init.'\n );\n }\n\n const headers = headersToRecord(init?.headers);\n for (const name of Object.keys(headers)) {\n if (SIGNING_RESERVED_HEADERS.has(name.toLowerCase())) {\n delete headers[name];\n }\n }\n const hasContentType = Object.keys(headers).some(k => k.toLowerCase() === 'content-type');\n if (!hasContentType && (init?.body !== undefined || method !== 'GET')) {\n headers['content-type'] = 'application/json';\n }\n const body = bodyToString(init?.body);\n\n const coverContentDigest =\n typeof options.coverContentDigest === 'function'\n ? (options.coverContentDigest as CoverContentDigestPredicate)(url, init)\n : options.coverContentDigest;\n const { coverContentDigest: _omit, ...signerOptionsBase } = options;\n const signerOptions: SignRequestOptions = { ...signerOptionsBase, coverContentDigest };\n\n const signed = await signRequestAsync({ method, url, headers, body }, provider, signerOptions);\n\n const mergedInit: RequestInit = { ...init, method, headers: signed.headers };\n if (body !== undefined && mergedInit.body === undefined) mergedInit.body = body;\n return upstream(url, mergedInit);\n };\n}\n\nfunction headersToRecord(headers: HeadersInit | Headers | undefined): Record<string, string> {\n if (!headers) return {};\n if (headers instanceof Headers) {\n const out: Record<string, string> = {};\n headers.forEach((v, k) => {\n out[k] = v;\n });\n return out;\n }\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers);\n }\n return { ...(headers as Record<string, string>) };\n}\n\nfunction bodyToString(body: RequestInit['body']): string | undefined {\n if (body === undefined || body === null) return undefined;\n if (typeof body === 'string') return body;\n if (body instanceof Uint8Array) return decodeUtf8Strict(body);\n if (body instanceof ArrayBuffer) return decodeUtf8Strict(new Uint8Array(body));\n throw new TypeError(\n 'createSigningFetchAsync requires a string, Uint8Array, or ArrayBuffer body. FormData / Blob / ReadableStream are not supported because the signature must cover the exact wire bytes.'\n );\n}\n\n/**\n * Decode bytes to UTF-8, throwing on invalid sequences. See the matching\n * helper in `./fetch.ts` for the full rationale; both wrappers refuse\n * non-UTF-8 byte bodies so callers don't get silent body corruption.\n */\nfunction decodeUtf8Strict(bytes: Uint8Array): string {\n try {\n return new TextDecoder('utf-8', { fatal: true }).decode(bytes);\n } catch {\n throw new TypeError(\n 'createSigningFetchAsync received a Uint8Array/ArrayBuffer body that is not valid UTF-8. ' +\n 'Pass a string body, ensure the bytes are UTF-8, or sign the request manually with `signRequestAsync` against the exact wire bytes you intend to send.'\n );\n }\n}\n"],"mappings":"AAGA,SAAS,wBAAwB;AASjC,MAAM,2BAA2B,oBAAI,IAAI,CAAC,aAAa,mBAAmB,gBAAgB,CAAC;AAmBpF,SAAS,wBACd,UACA,UACA,UAA+B,CAAC,GACrB;AACX,SAAO,OAAO,OAAO,SAAS;AAC5B,UAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,iBAAiB,MAAM,MAAM,SAAS,IAAI,MAAM;AAChG,UAAM,UAAU,MAAM,WAAW,iBAAiB,UAAU,MAAM,SAAS,QAAQ,YAAY;AAC/F,UAAM,aAAa,QAAQ,eAAe,MAAM,WAAW;AAC3D,QAAI,CAAC,WAAW,KAAK,IAAI,EAAG,QAAO,SAAS,OAAO,IAAI;AAEvD,QAAI,iBAAiB,SAAS;AAC5B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,gBAAgB,MAAM,OAAO;AAC7C,eAAW,QAAQ,OAAO,KAAK,OAAO,GAAG;AACvC,UAAI,yBAAyB,IAAI,KAAK,YAAY,CAAC,GAAG;AACpD,eAAO,QAAQ,IAAI;AAAA,MACrB;AAAA,IACF;AACA,UAAM,iBAAiB,OAAO,KAAK,OAAO,EAAE,KAAK,OAAK,EAAE,YAAY,MAAM,cAAc;AACxF,QAAI,CAAC,mBAAmB,MAAM,SAAS,UAAa,WAAW,QAAQ;AACrE,cAAQ,cAAc,IAAI;AAAA,IAC5B;AACA,UAAM,OAAO,aAAa,MAAM,IAAI;AAEpC,UAAM,qBACJ,OAAO,QAAQ,uBAAuB,aACjC,QAAQ,mBAAmD,KAAK,IAAI,IACrE,QAAQ;AACd,UAAM,EAAE,oBAAoB,OAAO,GAAG,kBAAkB,IAAI;AAC5D,UAAM,gBAAoC,EAAE,GAAG,mBAAmB,mBAAmB;AAErF,UAAM,SAAS,MAAM,iBAAiB,EAAE,QAAQ,KAAK,SAAS,KAAK,GAAG,UAAU,aAAa;AAE7F,UAAM,aAA0B,EAAE,GAAG,MAAM,QAAQ,SAAS,OAAO,QAAQ;AAC3E,QAAI,SAAS,UAAa,WAAW,SAAS,OAAW,YAAW,OAAO;AAC3E,WAAO,SAAS,KAAK,UAAU;AAAA,EACjC;AACF;AAEA,SAAS,gBAAgB,SAAoE;AAC3F,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,MAAI,mBAAmB,SAAS;AAC9B,UAAM,MAA8B,CAAC;AACrC,YAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,UAAI,CAAC,IAAI;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,WAAO,OAAO,YAAY,OAAO;AAAA,EACnC;AACA,SAAO,EAAE,GAAI,QAAmC;AAClD;AAEA,SAAS,aAAa,MAA+C;AACnE,MAAI,SAAS,UAAa,SAAS,KAAM,QAAO;AAChD,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,MAAI,gBAAgB,WAAY,QAAO,iBAAiB,IAAI;AAC5D,MAAI,gBAAgB,YAAa,QAAO,iBAAiB,IAAI,WAAW,IAAI,CAAC;AAC7E,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAOA,SAAS,iBAAiB,OAA2B;AACnD,MAAI;AACF,WAAO,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,EAAE,OAAO,KAAK;AAAA,EAC/D,QAAQ;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACF;","names":[]}
@@ -1,9 +1,3 @@
1
- import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
2
- import { dirname as __adcpDirname } from 'node:path';
3
- import { createRequire as __adcpCreateRequire } from 'node:module';
4
- const __filename = __adcpFileURLToPath(import.meta.url);
5
- const __dirname = __adcpDirname(__filename);
6
- const require = __adcpCreateRequire(import.meta.url);
7
1
  import { signRequest } from "./signer.mjs";
8
2
  const SIGNING_RESERVED_HEADERS = /* @__PURE__ */ new Set(["signature", "signature-input", "content-digest"]);
9
3
  function createSigningFetch(upstream, key, options = {}) {