@adcp/sdk 14.0.0-beta.11 → 14.0.0-beta.13

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 (235) hide show
  1. package/bin/adcp-storyboard-sandbox.js +16 -0
  2. package/bin/adcp.js +28 -30
  3. package/dist/lib/index.d.mts +3 -3
  4. package/dist/lib/index.d.ts +3 -3
  5. package/dist/lib/index.d.ts.map +1 -1
  6. package/dist/lib/index.js +2 -0
  7. package/dist/lib/index.js.map +1 -1
  8. package/dist/lib/index.mjs +3 -1
  9. package/dist/lib/index.mjs.map +1 -1
  10. package/dist/lib/schemas/index.d.mts +385 -1
  11. package/dist/lib/schemas/index.d.ts +385 -1
  12. package/dist/lib/schemas/index.d.ts.map +1 -1
  13. package/dist/lib/schemas/index.js +13 -0
  14. package/dist/lib/schemas/index.js.map +1 -1
  15. package/dist/lib/schemas/index.mjs +11 -0
  16. package/dist/lib/schemas/index.mjs.map +1 -1
  17. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  18. package/dist/lib/server/create-adcp-server.d.mts +2 -2
  19. package/dist/lib/server/create-adcp-server.d.ts +2 -2
  20. package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
  21. package/dist/lib/server/create-adcp-server.js +6 -1
  22. package/dist/lib/server/create-adcp-server.js.map +1 -1
  23. package/dist/lib/server/create-adcp-server.mjs +6 -1
  24. package/dist/lib/server/create-adcp-server.mjs.map +1 -1
  25. package/dist/lib/server/decisioning/index.d.mts +3 -3
  26. package/dist/lib/server/decisioning/index.d.ts +3 -3
  27. package/dist/lib/server/decisioning/index.d.ts.map +1 -1
  28. package/dist/lib/server/decisioning/index.js.map +1 -1
  29. package/dist/lib/server/decisioning/index.mjs.map +1 -1
  30. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +24 -17
  31. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +24 -17
  32. package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
  33. package/dist/lib/server/decisioning/runtime/from-platform.js +71 -42
  34. package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
  35. package/dist/lib/server/decisioning/runtime/from-platform.mjs +75 -43
  36. package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
  37. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.mts +15 -21
  38. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts +15 -21
  39. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts.map +1 -1
  40. package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +100 -30
  41. package/dist/lib/server/decisioning/runtime/postgres-task-registry.js.map +1 -1
  42. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +100 -30
  43. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs.map +1 -1
  44. package/dist/lib/server/decisioning/runtime/task-registry.d.mts +30 -16
  45. package/dist/lib/server/decisioning/runtime/task-registry.d.ts +30 -16
  46. package/dist/lib/server/decisioning/runtime/task-registry.d.ts.map +1 -1
  47. package/dist/lib/server/decisioning/runtime/task-registry.js +40 -20
  48. package/dist/lib/server/decisioning/runtime/task-registry.js.map +1 -1
  49. package/dist/lib/server/decisioning/runtime/task-registry.mjs +38 -19
  50. package/dist/lib/server/decisioning/runtime/task-registry.mjs.map +1 -1
  51. package/dist/lib/server/decisioning/runtime/to-context.d.mts +2 -2
  52. package/dist/lib/server/decisioning/runtime/to-context.d.ts +2 -2
  53. package/dist/lib/server/decisioning/runtime/to-context.d.ts.map +1 -1
  54. package/dist/lib/server/decisioning/runtime/to-context.js +2 -2
  55. package/dist/lib/server/decisioning/runtime/to-context.js.map +1 -1
  56. package/dist/lib/server/decisioning/runtime/to-context.mjs +2 -2
  57. package/dist/lib/server/decisioning/runtime/to-context.mjs.map +1 -1
  58. package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.mts +3 -2
  59. package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts +3 -2
  60. package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts.map +1 -1
  61. package/dist/lib/server/decisioning/specialisms/creative-ad-server.js.map +1 -1
  62. package/dist/lib/server/decisioning/specialisms/creative.d.mts +10 -10
  63. package/dist/lib/server/decisioning/specialisms/creative.d.ts +10 -10
  64. package/dist/lib/server/decisioning/specialisms/creative.d.ts.map +1 -1
  65. package/dist/lib/server/decisioning/specialisms/creative.js.map +1 -1
  66. package/dist/lib/server/index.d.mts +1 -1
  67. package/dist/lib/server/index.d.ts +1 -1
  68. package/dist/lib/server/index.d.ts.map +1 -1
  69. package/dist/lib/server/index.js.map +1 -1
  70. package/dist/lib/server/index.mjs.map +1 -1
  71. package/dist/lib/signing/agent-context.d.mts +1 -0
  72. package/dist/lib/signing/agent-context.d.ts +1 -0
  73. package/dist/lib/signing/agent-context.d.ts.map +1 -1
  74. package/dist/lib/signing/agent-context.js +37 -2
  75. package/dist/lib/signing/agent-context.js.map +1 -1
  76. package/dist/lib/signing/agent-context.mjs +38 -3
  77. package/dist/lib/signing/agent-context.mjs.map +1 -1
  78. package/dist/lib/signing/agent-fetch.d.mts +1 -2
  79. package/dist/lib/signing/agent-fetch.d.ts +1 -2
  80. package/dist/lib/signing/agent-fetch.d.ts.map +1 -1
  81. package/dist/lib/signing/agent-fetch.js +2 -0
  82. package/dist/lib/signing/agent-fetch.js.map +1 -1
  83. package/dist/lib/signing/agent-fetch.mjs +2 -0
  84. package/dist/lib/signing/agent-fetch.mjs.map +1 -1
  85. package/dist/lib/signing/agent-resolver/etld.js.map +1 -1
  86. package/dist/lib/signing/agent-resolver/etld.mjs.map +1 -1
  87. package/dist/lib/testing/client.d.mts +6 -0
  88. package/dist/lib/testing/client.d.ts +6 -0
  89. package/dist/lib/testing/client.d.ts.map +1 -1
  90. package/dist/lib/testing/client.js +76 -4
  91. package/dist/lib/testing/client.js.map +1 -1
  92. package/dist/lib/testing/client.mjs +75 -4
  93. package/dist/lib/testing/client.mjs.map +1 -1
  94. package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
  95. package/dist/lib/testing/compliance/comply.js +6 -0
  96. package/dist/lib/testing/compliance/comply.js.map +1 -1
  97. package/dist/lib/testing/compliance/comply.mjs +7 -1
  98. package/dist/lib/testing/compliance/comply.mjs.map +1 -1
  99. package/dist/lib/testing/storyboard/default-invariants.d.ts.map +1 -1
  100. package/dist/lib/testing/storyboard/default-invariants.js +11 -2
  101. package/dist/lib/testing/storyboard/default-invariants.js.map +1 -1
  102. package/dist/lib/testing/storyboard/default-invariants.mjs +11 -2
  103. package/dist/lib/testing/storyboard/default-invariants.mjs.map +1 -1
  104. package/dist/lib/testing/storyboard/index.d.mts +1 -1
  105. package/dist/lib/testing/storyboard/index.d.ts +1 -1
  106. package/dist/lib/testing/storyboard/index.d.ts.map +1 -1
  107. package/dist/lib/testing/storyboard/index.js.map +1 -1
  108. package/dist/lib/testing/storyboard/index.mjs.map +1 -1
  109. package/dist/lib/testing/storyboard/loader.d.ts.map +1 -1
  110. package/dist/lib/testing/storyboard/loader.js +14 -0
  111. package/dist/lib/testing/storyboard/loader.js.map +1 -1
  112. package/dist/lib/testing/storyboard/loader.mjs +14 -0
  113. package/dist/lib/testing/storyboard/loader.mjs.map +1 -1
  114. package/dist/lib/testing/storyboard/phase-condition.d.mts +41 -0
  115. package/dist/lib/testing/storyboard/phase-condition.d.ts +42 -0
  116. package/dist/lib/testing/storyboard/phase-condition.d.ts.map +1 -0
  117. package/dist/lib/testing/storyboard/phase-condition.js +215 -0
  118. package/dist/lib/testing/storyboard/phase-condition.js.map +1 -0
  119. package/dist/lib/testing/storyboard/phase-condition.mjs +189 -0
  120. package/dist/lib/testing/storyboard/phase-condition.mjs.map +1 -0
  121. package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -1
  122. package/dist/lib/testing/storyboard/request-builder.js +15 -2
  123. package/dist/lib/testing/storyboard/request-builder.js.map +1 -1
  124. package/dist/lib/testing/storyboard/request-builder.mjs +15 -2
  125. package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
  126. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.mts +15 -0
  127. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.ts +16 -0
  128. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.ts.map +1 -0
  129. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.js +106 -0
  130. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.js.map +1 -0
  131. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.mjs +82 -0
  132. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.mjs.map +1 -0
  133. package/dist/lib/testing/storyboard/request-signing/test-kit.d.mts +15 -0
  134. package/dist/lib/testing/storyboard/request-signing/test-kit.d.ts +15 -0
  135. package/dist/lib/testing/storyboard/request-signing/test-kit.d.ts.map +1 -1
  136. package/dist/lib/testing/storyboard/request-signing/test-kit.js +58 -0
  137. package/dist/lib/testing/storyboard/request-signing/test-kit.js.map +1 -1
  138. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs +58 -0
  139. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs.map +1 -1
  140. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
  141. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
  142. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts.map +1 -1
  143. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +7 -1
  144. package/dist/lib/testing/storyboard/request-signing/vector-loader.js.map +1 -1
  145. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +6 -1
  146. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
  147. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  148. package/dist/lib/testing/storyboard/runner.js +67 -24
  149. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  150. package/dist/lib/testing/storyboard/runner.mjs +67 -24
  151. package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
  152. package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -1
  153. package/dist/lib/testing/storyboard/task-map.js +6 -2
  154. package/dist/lib/testing/storyboard/task-map.js.map +1 -1
  155. package/dist/lib/testing/storyboard/task-map.mjs +6 -2
  156. package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
  157. package/dist/lib/testing/storyboard/types.d.mts +5 -4
  158. package/dist/lib/testing/storyboard/types.d.ts +5 -4
  159. package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
  160. package/dist/lib/testing/storyboard/types.js.map +1 -1
  161. package/dist/lib/testing/storyboard/types.mjs.map +1 -1
  162. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  163. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  164. package/dist/lib/testing/storyboard/webhook-assertions.d.ts.map +1 -1
  165. package/dist/lib/testing/storyboard/webhook-assertions.js +60 -4
  166. package/dist/lib/testing/storyboard/webhook-assertions.js.map +1 -1
  167. package/dist/lib/testing/storyboard/webhook-assertions.mjs +60 -4
  168. package/dist/lib/testing/storyboard/webhook-assertions.mjs.map +1 -1
  169. package/dist/lib/testing/storyboard/webhook-receiver.d.mts +15 -0
  170. package/dist/lib/testing/storyboard/webhook-receiver.d.ts +15 -0
  171. package/dist/lib/testing/storyboard/webhook-receiver.d.ts.map +1 -1
  172. package/dist/lib/testing/storyboard/webhook-receiver.js +57 -6
  173. package/dist/lib/testing/storyboard/webhook-receiver.js.map +1 -1
  174. package/dist/lib/testing/storyboard/webhook-receiver.mjs +57 -6
  175. package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
  176. package/dist/lib/testing/types.d.mts +12 -0
  177. package/dist/lib/testing/types.d.ts +12 -0
  178. package/dist/lib/testing/types.d.ts.map +1 -1
  179. package/dist/lib/testing/types.js.map +1 -1
  180. package/dist/lib/types/comply-test-controller.d.ts +1 -14
  181. package/dist/lib/types/core.generated.d.mts +6 -3
  182. package/dist/lib/types/core.generated.d.ts +6 -3
  183. package/dist/lib/types/core.generated.d.ts.map +1 -1
  184. package/dist/lib/types/core.generated.js.map +1 -1
  185. package/dist/lib/types/get-products.d.ts +1 -14
  186. package/dist/lib/types/index.d.mts +1 -1
  187. package/dist/lib/types/index.d.ts +1 -1
  188. package/dist/lib/types/index.d.ts.map +1 -1
  189. package/dist/lib/types/index.js.map +1 -1
  190. package/dist/lib/types/index.mjs.map +1 -1
  191. package/dist/lib/types/list-transformers.d.ts +9 -5
  192. package/dist/lib/types/schemas.generated.d.ts +23 -352
  193. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  194. package/dist/lib/types/schemas.generated.js +7 -4
  195. package/dist/lib/types/schemas.generated.js.map +1 -1
  196. package/dist/lib/types/schemas.generated.mjs +6 -4
  197. package/dist/lib/types/schemas.generated.mjs.map +1 -1
  198. package/dist/lib/types/server-payload-aliases.d.mts +2 -1
  199. package/dist/lib/types/server-payload-aliases.d.ts +2 -1
  200. package/dist/lib/types/server-payload-aliases.d.ts.map +1 -1
  201. package/dist/lib/types/server-payload-aliases.js.map +1 -1
  202. package/dist/lib/types/tools.generated.d.mts +6 -3
  203. package/dist/lib/types/tools.generated.d.ts +6 -3
  204. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  205. package/dist/lib/types/tools.generated.js.map +1 -1
  206. package/dist/lib/utils/build-creative-return-builders.d.mts +5 -1
  207. package/dist/lib/utils/build-creative-return-builders.d.ts +5 -1
  208. package/dist/lib/utils/build-creative-return-builders.d.ts.map +1 -1
  209. package/dist/lib/utils/build-creative-return-builders.js +9 -3
  210. package/dist/lib/utils/build-creative-return-builders.js.map +1 -1
  211. package/dist/lib/utils/build-creative-return-builders.mjs +7 -2
  212. package/dist/lib/utils/build-creative-return-builders.mjs.map +1 -1
  213. package/dist/lib/utils/response-unwrapper.js +1 -1
  214. package/dist/lib/utils/response-unwrapper.js.map +1 -1
  215. package/dist/lib/utils/response-unwrapper.mjs +1 -1
  216. package/dist/lib/utils/response-unwrapper.mjs.map +1 -1
  217. package/dist/lib/validation/schema-loader.d.ts.map +1 -1
  218. package/dist/lib/validation/schema-loader.js +16 -7
  219. package/dist/lib/validation/schema-loader.js.map +1 -1
  220. package/dist/lib/validation/schema-loader.mjs +16 -7
  221. package/dist/lib/validation/schema-loader.mjs.map +1 -1
  222. package/dist/lib/version.d.mts +3 -3
  223. package/dist/lib/version.d.ts +3 -3
  224. package/dist/lib/version.js +3 -3
  225. package/dist/lib/version.js.map +1 -1
  226. package/dist/lib/version.mjs +3 -3
  227. package/dist/lib/version.mjs.map +1 -1
  228. package/docs/llms.txt +2 -2
  229. package/docs/migration-5.x-to-6.x.md +3 -2
  230. package/docs/migration-task-registry-scoping.md +61 -0
  231. package/examples/hello_seller_adapter_guaranteed.ts +1 -1
  232. package/package.json +5 -5
  233. package/skills/build-decisioning-creative-template/SKILL.md +2 -2
  234. package/skills/build-decisioning-platform/SKILL.md +4 -2
  235. package/skills/build-decisioning-platform/advanced/REFERENCE.md +7 -6
@@ -18,11 +18,26 @@ export interface RateAbuseContract {
18
18
  production_min_per_keyid_cap_requests: number;
19
19
  window_seconds: number;
20
20
  }
21
+ export interface FunctionalDispatchContract {
22
+ signing_keyid: string;
23
+ signer_agent_url: string;
24
+ operation_selection: {
25
+ capability_path: 'request_signing';
26
+ sign_required_for: boolean;
27
+ sign_supported_for: boolean;
28
+ };
29
+ content_digest_policy_source: 'request_signing.covers_content_digest';
30
+ preserve_transport_auth: boolean;
31
+ fresh_signature_per_dispatch: boolean;
32
+ bootstrap_operations_unsigned: string[];
33
+ unavailable_behavior: 'not_applicable';
34
+ }
21
35
  export interface SignedRequestsRunnerContract {
22
36
  id: string;
23
37
  endpoint_scope: 'sandbox' | string;
24
38
  harness_mode: 'black_box' | 'white_box';
25
39
  runner_signing_keys: RunnerSigningKey[];
40
+ functional_dispatch?: FunctionalDispatchContract;
26
41
  stateful_vector_contract: {
27
42
  replay_window: ReplayWindowContract;
28
43
  revocation: RevocationContract;
@@ -18,11 +18,26 @@ export interface RateAbuseContract {
18
18
  production_min_per_keyid_cap_requests: number;
19
19
  window_seconds: number;
20
20
  }
21
+ export interface FunctionalDispatchContract {
22
+ signing_keyid: string;
23
+ signer_agent_url: string;
24
+ operation_selection: {
25
+ capability_path: 'request_signing';
26
+ sign_required_for: boolean;
27
+ sign_supported_for: boolean;
28
+ };
29
+ content_digest_policy_source: 'request_signing.covers_content_digest';
30
+ preserve_transport_auth: boolean;
31
+ fresh_signature_per_dispatch: boolean;
32
+ bootstrap_operations_unsigned: string[];
33
+ unavailable_behavior: 'not_applicable';
34
+ }
21
35
  export interface SignedRequestsRunnerContract {
22
36
  id: string;
23
37
  endpoint_scope: 'sandbox' | string;
24
38
  harness_mode: 'black_box' | 'white_box';
25
39
  runner_signing_keys: RunnerSigningKey[];
40
+ functional_dispatch?: FunctionalDispatchContract;
26
41
  stateful_vector_contract: {
27
42
  replay_window: ReplayWindowContract;
28
43
  revocation: RevocationContract;
@@ -1 +1 @@
1
- {"version":3,"file":"test-kit.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,SAAS,GAAG,mBAAmB,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,gBAAgB,CAAC;IACrC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC,EAAE,MAAM,CAAC;IAC9C,qCAAqC,EAAE,MAAM,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC,YAAY,EAAE,WAAW,GAAG,WAAW,CAAC;IACxC,mBAAmB,EAAE,gBAAgB,EAAE,CAAC;IACxC,wBAAwB,EAAE;QACxB,aAAa,EAAE,oBAAoB,CAAC;QACpC,UAAU,EAAE,kBAAkB,CAAC;QAC/B,UAAU,EAAE,iBAAiB,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,kBAAuB,GAC/B,4BAA4B,GAAG,SAAS,CAY1C"}
1
+ {"version":3,"file":"test-kit.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,SAAS,GAAG,mBAAmB,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,gBAAgB,CAAC;IACrC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC,EAAE,MAAM,CAAC;IAC9C,qCAAqC,EAAE,MAAM,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE;QACnB,eAAe,EAAE,iBAAiB,CAAC;QACnC,iBAAiB,EAAE,OAAO,CAAC;QAC3B,kBAAkB,EAAE,OAAO,CAAC;KAC7B,CAAC;IACF,4BAA4B,EAAE,uCAAuC,CAAC;IACtE,uBAAuB,EAAE,OAAO,CAAC;IACjC,4BAA4B,EAAE,OAAO,CAAC;IACtC,6BAA6B,EAAE,MAAM,EAAE,CAAC;IACxC,oBAAoB,EAAE,gBAAgB,CAAC;CACxC;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC,YAAY,EAAE,WAAW,GAAG,WAAW,CAAC;IACxC,mBAAmB,EAAE,gBAAgB,EAAE,CAAC;IACxC,mBAAmB,CAAC,EAAE,0BAA0B,CAAC;IACjD,wBAAwB,EAAE;QACxB,aAAa,EAAE,oBAAoB,CAAC;QACpC,UAAU,EAAE,kBAAkB,CAAC;QAC/B,UAAU,EAAE,iBAAiB,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,kBAAuB,GAC/B,4BAA4B,GAAG,SAAS,CAc1C"}
@@ -30,14 +30,62 @@ function loadSignedRequestsRunnerContract(options = {}) {
30
30
  const path = (0, import_path.join)(cacheDir, "test-kits", "signed-requests-runner.yaml");
31
31
  if (!(0, import_fs.existsSync)(path)) return void 0;
32
32
  const raw = (0, import_yaml.parse)((0, import_fs.readFileSync)(path, "utf-8"));
33
+ const functionalDispatch = parseFunctionalDispatch(raw.functional_dispatch);
33
34
  return {
34
35
  id: assertString(raw.id, "id"),
35
36
  endpoint_scope: assertString(raw.endpoint_scope, "endpoint_scope"),
36
37
  harness_mode: parseHarnessMode(raw.harness_mode),
37
38
  runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),
39
+ ...functionalDispatch && { functional_dispatch: functionalDispatch },
38
40
  stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract)
39
41
  };
40
42
  }
43
+ function parseFunctionalDispatch(raw) {
44
+ if (raw === void 0) return void 0;
45
+ const r = asObject(raw, "functional_dispatch");
46
+ const selection = asObject(r.operation_selection, "functional_dispatch.operation_selection");
47
+ const capabilityPath = assertString(
48
+ selection.capability_path,
49
+ "functional_dispatch.operation_selection.capability_path"
50
+ );
51
+ if (capabilityPath !== "request_signing") {
52
+ throw new Error('functional_dispatch.operation_selection.capability_path must be "request_signing"');
53
+ }
54
+ const digestSource = assertString(r.content_digest_policy_source, "functional_dispatch.content_digest_policy_source");
55
+ if (digestSource !== "request_signing.covers_content_digest") {
56
+ throw new Error('functional_dispatch.content_digest_policy_source must be "request_signing.covers_content_digest"');
57
+ }
58
+ const unavailable = assertString(r.unavailable_behavior, "functional_dispatch.unavailable_behavior");
59
+ if (unavailable !== "not_applicable") {
60
+ throw new Error('functional_dispatch.unavailable_behavior must be "not_applicable"');
61
+ }
62
+ return {
63
+ signing_keyid: assertString(r.signing_keyid, "functional_dispatch.signing_keyid"),
64
+ signer_agent_url: assertString(r.signer_agent_url, "functional_dispatch.signer_agent_url"),
65
+ operation_selection: {
66
+ capability_path: "request_signing",
67
+ sign_required_for: assertBoolean(
68
+ selection.sign_required_for,
69
+ "functional_dispatch.operation_selection.sign_required_for"
70
+ ),
71
+ sign_supported_for: assertBoolean(
72
+ selection.sign_supported_for,
73
+ "functional_dispatch.operation_selection.sign_supported_for"
74
+ )
75
+ },
76
+ content_digest_policy_source: "request_signing.covers_content_digest",
77
+ preserve_transport_auth: assertBoolean(r.preserve_transport_auth, "functional_dispatch.preserve_transport_auth"),
78
+ fresh_signature_per_dispatch: assertBoolean(
79
+ r.fresh_signature_per_dispatch,
80
+ "functional_dispatch.fresh_signature_per_dispatch"
81
+ ),
82
+ bootstrap_operations_unsigned: assertStringArray(
83
+ r.bootstrap_operations_unsigned,
84
+ "functional_dispatch.bootstrap_operations_unsigned"
85
+ ),
86
+ unavailable_behavior: "not_applicable"
87
+ };
88
+ }
41
89
  function parseHarnessMode(raw) {
42
90
  const s = assertString(raw, "harness_mode");
43
91
  if (s !== "black_box" && s !== "white_box") {
@@ -114,6 +162,16 @@ function assertNumber(v, where) {
114
162
  if (typeof v !== "number") throw new Error(`${where} must be number`);
115
163
  return v;
116
164
  }
165
+ function assertBoolean(v, where) {
166
+ if (typeof v !== "boolean") throw new Error(`${where} must be boolean`);
167
+ return v;
168
+ }
169
+ function assertStringArray(v, where) {
170
+ if (!Array.isArray(v) || v.some((item) => typeof item !== "string")) {
171
+ throw new Error(`${where} must be string[]`);
172
+ }
173
+ return v;
174
+ }
117
175
  // Annotate the CommonJS export names for ESM import in node:
118
176
  0 && (module.exports = {
119
177
  loadSignedRequestsRunnerContract
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from '../compliance';\n\nexport interface RunnerSigningKey {\n keyid: string;\n alg: 'ed25519' | 'ecdsa-p256-sha256';\n}\n\nexport interface ReplayWindowContract {\n vector_id: string;\n black_box_behavior: 'repeat_request';\n max_interval_seconds: number;\n min_replay_ttl_seconds: number;\n}\n\nexport interface RevocationContract {\n vector_id: string;\n pre_revoked_keyid: string;\n}\n\nexport interface RateAbuseContract {\n vector_id: string;\n grading_target_per_keyid_cap_requests: number;\n production_min_per_keyid_cap_requests: number;\n window_seconds: number;\n}\n\nexport interface SignedRequestsRunnerContract {\n id: string;\n endpoint_scope: 'sandbox' | string;\n harness_mode: 'black_box' | 'white_box';\n runner_signing_keys: RunnerSigningKey[];\n stateful_vector_contract: {\n replay_window: ReplayWindowContract;\n revocation: RevocationContract;\n rate_abuse: RateAbuseContract;\n };\n}\n\nexport interface LoadTestKitOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Load and parse `test-kits/signed-requests-runner.yaml` from the compliance\n * cache. Returns undefined when the file is absent (upstream pre-adcp#2353\n * caches, or a sync in progress) — callers must decide how to degrade.\n */\nexport function loadSignedRequestsRunnerContract(\n options: LoadTestKitOptions = {}\n): SignedRequestsRunnerContract | undefined {\n const cacheDir = getComplianceCacheDir(options);\n const path = join(cacheDir, 'test-kits', 'signed-requests-runner.yaml');\n if (!existsSync(path)) return undefined;\n const raw = parse(readFileSync(path, 'utf-8')) as Record<string, unknown>;\n return {\n id: assertString(raw.id, 'id'),\n endpoint_scope: assertString(raw.endpoint_scope, 'endpoint_scope'),\n harness_mode: parseHarnessMode(raw.harness_mode),\n runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),\n stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract),\n };\n}\n\nfunction parseHarnessMode(raw: unknown): 'black_box' | 'white_box' {\n const s = assertString(raw, 'harness_mode');\n if (s !== 'black_box' && s !== 'white_box') {\n throw new Error(`test-kit harness_mode must be \"black_box\" or \"white_box\", got \"${s}\"`);\n }\n return s;\n}\n\nfunction parseSigningKeys(raw: unknown): RunnerSigningKey[] {\n if (!Array.isArray(raw)) throw new Error('runner_signing_keys must be an array');\n return raw.map((entry, i) => {\n const r = entry as Record<string, unknown>;\n const alg = assertString(r.alg, `runner_signing_keys[${i}].alg`);\n if (alg !== 'ed25519' && alg !== 'ecdsa-p256-sha256') {\n throw new Error(`runner_signing_keys[${i}].alg: unsupported \"${alg}\"`);\n }\n return { keyid: assertString(r.keyid, `runner_signing_keys[${i}].keyid`), alg };\n });\n}\n\nfunction parseStatefulContracts(raw: unknown): SignedRequestsRunnerContract['stateful_vector_contract'] {\n if (!raw || typeof raw !== 'object') {\n throw new Error('stateful_vector_contract block missing');\n }\n const r = raw as Record<string, unknown>;\n return {\n replay_window: parseReplay(r.replay_window),\n revocation: parseRevocation(r.revocation),\n rate_abuse: parseRateAbuse(r.rate_abuse),\n };\n}\n\nfunction parseReplay(raw: unknown): ReplayWindowContract {\n const r = asObject(raw, 'stateful_vector_contract.replay_window');\n const behavior = assertString(r.black_box_behavior, 'replay_window.black_box_behavior');\n if (behavior !== 'repeat_request') {\n throw new Error(`replay_window.black_box_behavior must be \"repeat_request\", got \"${behavior}\"`);\n }\n return {\n vector_id: assertString(r.vector_id, 'replay_window.vector_id'),\n black_box_behavior: 'repeat_request',\n max_interval_seconds: assertNumber(r.max_interval_seconds, 'replay_window.max_interval_seconds'),\n min_replay_ttl_seconds: assertNumber(r.min_replay_ttl_seconds, 'replay_window.min_replay_ttl_seconds'),\n };\n}\n\nfunction parseRevocation(raw: unknown): RevocationContract {\n const r = asObject(raw, 'stateful_vector_contract.revocation');\n return {\n vector_id: assertString(r.vector_id, 'revocation.vector_id'),\n pre_revoked_keyid: assertString(r.pre_revoked_keyid, 'revocation.pre_revoked_keyid'),\n };\n}\n\nfunction parseRateAbuse(raw: unknown): RateAbuseContract {\n const r = asObject(raw, 'stateful_vector_contract.rate_abuse');\n return {\n vector_id: assertString(r.vector_id, 'rate_abuse.vector_id'),\n grading_target_per_keyid_cap_requests: assertNumber(\n r.grading_target_per_keyid_cap_requests,\n 'rate_abuse.grading_target_per_keyid_cap_requests'\n ),\n production_min_per_keyid_cap_requests: assertNumber(\n r.production_min_per_keyid_cap_requests,\n 'rate_abuse.production_min_per_keyid_cap_requests'\n ),\n window_seconds: assertNumber(r.window_seconds, 'rate_abuse.window_seconds'),\n };\n}\n\nfunction asObject(raw: unknown, where: string): Record<string, unknown> {\n if (!raw || typeof raw !== 'object') throw new Error(`${where} missing or not an object`);\n return raw as Record<string, unknown>;\n}\n\nfunction assertString(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction assertNumber(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from '../compliance';\n\nexport interface RunnerSigningKey {\n keyid: string;\n alg: 'ed25519' | 'ecdsa-p256-sha256';\n}\n\nexport interface ReplayWindowContract {\n vector_id: string;\n black_box_behavior: 'repeat_request';\n max_interval_seconds: number;\n min_replay_ttl_seconds: number;\n}\n\nexport interface RevocationContract {\n vector_id: string;\n pre_revoked_keyid: string;\n}\n\nexport interface RateAbuseContract {\n vector_id: string;\n grading_target_per_keyid_cap_requests: number;\n production_min_per_keyid_cap_requests: number;\n window_seconds: number;\n}\n\nexport interface FunctionalDispatchContract {\n signing_keyid: string;\n signer_agent_url: string;\n operation_selection: {\n capability_path: 'request_signing';\n sign_required_for: boolean;\n sign_supported_for: boolean;\n };\n content_digest_policy_source: 'request_signing.covers_content_digest';\n preserve_transport_auth: boolean;\n fresh_signature_per_dispatch: boolean;\n bootstrap_operations_unsigned: string[];\n unavailable_behavior: 'not_applicable';\n}\n\nexport interface SignedRequestsRunnerContract {\n id: string;\n endpoint_scope: 'sandbox' | string;\n harness_mode: 'black_box' | 'white_box';\n runner_signing_keys: RunnerSigningKey[];\n functional_dispatch?: FunctionalDispatchContract;\n stateful_vector_contract: {\n replay_window: ReplayWindowContract;\n revocation: RevocationContract;\n rate_abuse: RateAbuseContract;\n };\n}\n\nexport interface LoadTestKitOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Load and parse `test-kits/signed-requests-runner.yaml` from the compliance\n * cache. Returns undefined when the file is absent (upstream pre-adcp#2353\n * caches, or a sync in progress) — callers must decide how to degrade.\n */\nexport function loadSignedRequestsRunnerContract(\n options: LoadTestKitOptions = {}\n): SignedRequestsRunnerContract | undefined {\n const cacheDir = getComplianceCacheDir(options);\n const path = join(cacheDir, 'test-kits', 'signed-requests-runner.yaml');\n if (!existsSync(path)) return undefined;\n const raw = parse(readFileSync(path, 'utf-8')) as Record<string, unknown>;\n const functionalDispatch = parseFunctionalDispatch(raw.functional_dispatch);\n return {\n id: assertString(raw.id, 'id'),\n endpoint_scope: assertString(raw.endpoint_scope, 'endpoint_scope'),\n harness_mode: parseHarnessMode(raw.harness_mode),\n runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),\n ...(functionalDispatch && { functional_dispatch: functionalDispatch }),\n stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract),\n };\n}\n\nfunction parseFunctionalDispatch(raw: unknown): FunctionalDispatchContract | undefined {\n if (raw === undefined) return undefined;\n const r = asObject(raw, 'functional_dispatch');\n const selection = asObject(r.operation_selection, 'functional_dispatch.operation_selection');\n const capabilityPath = assertString(\n selection.capability_path,\n 'functional_dispatch.operation_selection.capability_path'\n );\n if (capabilityPath !== 'request_signing') {\n throw new Error('functional_dispatch.operation_selection.capability_path must be \"request_signing\"');\n }\n const digestSource = assertString(r.content_digest_policy_source, 'functional_dispatch.content_digest_policy_source');\n if (digestSource !== 'request_signing.covers_content_digest') {\n throw new Error('functional_dispatch.content_digest_policy_source must be \"request_signing.covers_content_digest\"');\n }\n const unavailable = assertString(r.unavailable_behavior, 'functional_dispatch.unavailable_behavior');\n if (unavailable !== 'not_applicable') {\n throw new Error('functional_dispatch.unavailable_behavior must be \"not_applicable\"');\n }\n return {\n signing_keyid: assertString(r.signing_keyid, 'functional_dispatch.signing_keyid'),\n signer_agent_url: assertString(r.signer_agent_url, 'functional_dispatch.signer_agent_url'),\n operation_selection: {\n capability_path: 'request_signing',\n sign_required_for: assertBoolean(\n selection.sign_required_for,\n 'functional_dispatch.operation_selection.sign_required_for'\n ),\n sign_supported_for: assertBoolean(\n selection.sign_supported_for,\n 'functional_dispatch.operation_selection.sign_supported_for'\n ),\n },\n content_digest_policy_source: 'request_signing.covers_content_digest',\n preserve_transport_auth: assertBoolean(r.preserve_transport_auth, 'functional_dispatch.preserve_transport_auth'),\n fresh_signature_per_dispatch: assertBoolean(\n r.fresh_signature_per_dispatch,\n 'functional_dispatch.fresh_signature_per_dispatch'\n ),\n bootstrap_operations_unsigned: assertStringArray(\n r.bootstrap_operations_unsigned,\n 'functional_dispatch.bootstrap_operations_unsigned'\n ),\n unavailable_behavior: 'not_applicable',\n };\n}\n\nfunction parseHarnessMode(raw: unknown): 'black_box' | 'white_box' {\n const s = assertString(raw, 'harness_mode');\n if (s !== 'black_box' && s !== 'white_box') {\n throw new Error(`test-kit harness_mode must be \"black_box\" or \"white_box\", got \"${s}\"`);\n }\n return s;\n}\n\nfunction parseSigningKeys(raw: unknown): RunnerSigningKey[] {\n if (!Array.isArray(raw)) throw new Error('runner_signing_keys must be an array');\n return raw.map((entry, i) => {\n const r = entry as Record<string, unknown>;\n const alg = assertString(r.alg, `runner_signing_keys[${i}].alg`);\n if (alg !== 'ed25519' && alg !== 'ecdsa-p256-sha256') {\n throw new Error(`runner_signing_keys[${i}].alg: unsupported \"${alg}\"`);\n }\n return { keyid: assertString(r.keyid, `runner_signing_keys[${i}].keyid`), alg };\n });\n}\n\nfunction parseStatefulContracts(raw: unknown): SignedRequestsRunnerContract['stateful_vector_contract'] {\n if (!raw || typeof raw !== 'object') {\n throw new Error('stateful_vector_contract block missing');\n }\n const r = raw as Record<string, unknown>;\n return {\n replay_window: parseReplay(r.replay_window),\n revocation: parseRevocation(r.revocation),\n rate_abuse: parseRateAbuse(r.rate_abuse),\n };\n}\n\nfunction parseReplay(raw: unknown): ReplayWindowContract {\n const r = asObject(raw, 'stateful_vector_contract.replay_window');\n const behavior = assertString(r.black_box_behavior, 'replay_window.black_box_behavior');\n if (behavior !== 'repeat_request') {\n throw new Error(`replay_window.black_box_behavior must be \"repeat_request\", got \"${behavior}\"`);\n }\n return {\n vector_id: assertString(r.vector_id, 'replay_window.vector_id'),\n black_box_behavior: 'repeat_request',\n max_interval_seconds: assertNumber(r.max_interval_seconds, 'replay_window.max_interval_seconds'),\n min_replay_ttl_seconds: assertNumber(r.min_replay_ttl_seconds, 'replay_window.min_replay_ttl_seconds'),\n };\n}\n\nfunction parseRevocation(raw: unknown): RevocationContract {\n const r = asObject(raw, 'stateful_vector_contract.revocation');\n return {\n vector_id: assertString(r.vector_id, 'revocation.vector_id'),\n pre_revoked_keyid: assertString(r.pre_revoked_keyid, 'revocation.pre_revoked_keyid'),\n };\n}\n\nfunction parseRateAbuse(raw: unknown): RateAbuseContract {\n const r = asObject(raw, 'stateful_vector_contract.rate_abuse');\n return {\n vector_id: assertString(r.vector_id, 'rate_abuse.vector_id'),\n grading_target_per_keyid_cap_requests: assertNumber(\n r.grading_target_per_keyid_cap_requests,\n 'rate_abuse.grading_target_per_keyid_cap_requests'\n ),\n production_min_per_keyid_cap_requests: assertNumber(\n r.production_min_per_keyid_cap_requests,\n 'rate_abuse.production_min_per_keyid_cap_requests'\n ),\n window_seconds: assertNumber(r.window_seconds, 'rate_abuse.window_seconds'),\n };\n}\n\nfunction asObject(raw: unknown, where: string): Record<string, unknown> {\n if (!raw || typeof raw !== 'object') throw new Error(`${where} missing or not an object`);\n return raw as Record<string, unknown>;\n}\n\nfunction assertString(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction assertNumber(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n\nfunction assertBoolean(v: unknown, where: string): boolean {\n if (typeof v !== 'boolean') throw new Error(`${where} must be boolean`);\n return v;\n}\n\nfunction assertStringArray(v: unknown, where: string): string[] {\n if (!Array.isArray(v) || v.some(item => typeof item !== 'string')) {\n throw new Error(`${where} must be string[]`);\n }\n return v;\n}\n"],"mappings":"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","names":[]}
@@ -7,14 +7,62 @@ function loadSignedRequestsRunnerContract(options = {}) {
7
7
  const path = join(cacheDir, "test-kits", "signed-requests-runner.yaml");
8
8
  if (!existsSync(path)) return void 0;
9
9
  const raw = parse(readFileSync(path, "utf-8"));
10
+ const functionalDispatch = parseFunctionalDispatch(raw.functional_dispatch);
10
11
  return {
11
12
  id: assertString(raw.id, "id"),
12
13
  endpoint_scope: assertString(raw.endpoint_scope, "endpoint_scope"),
13
14
  harness_mode: parseHarnessMode(raw.harness_mode),
14
15
  runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),
16
+ ...functionalDispatch && { functional_dispatch: functionalDispatch },
15
17
  stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract)
16
18
  };
17
19
  }
20
+ function parseFunctionalDispatch(raw) {
21
+ if (raw === void 0) return void 0;
22
+ const r = asObject(raw, "functional_dispatch");
23
+ const selection = asObject(r.operation_selection, "functional_dispatch.operation_selection");
24
+ const capabilityPath = assertString(
25
+ selection.capability_path,
26
+ "functional_dispatch.operation_selection.capability_path"
27
+ );
28
+ if (capabilityPath !== "request_signing") {
29
+ throw new Error('functional_dispatch.operation_selection.capability_path must be "request_signing"');
30
+ }
31
+ const digestSource = assertString(r.content_digest_policy_source, "functional_dispatch.content_digest_policy_source");
32
+ if (digestSource !== "request_signing.covers_content_digest") {
33
+ throw new Error('functional_dispatch.content_digest_policy_source must be "request_signing.covers_content_digest"');
34
+ }
35
+ const unavailable = assertString(r.unavailable_behavior, "functional_dispatch.unavailable_behavior");
36
+ if (unavailable !== "not_applicable") {
37
+ throw new Error('functional_dispatch.unavailable_behavior must be "not_applicable"');
38
+ }
39
+ return {
40
+ signing_keyid: assertString(r.signing_keyid, "functional_dispatch.signing_keyid"),
41
+ signer_agent_url: assertString(r.signer_agent_url, "functional_dispatch.signer_agent_url"),
42
+ operation_selection: {
43
+ capability_path: "request_signing",
44
+ sign_required_for: assertBoolean(
45
+ selection.sign_required_for,
46
+ "functional_dispatch.operation_selection.sign_required_for"
47
+ ),
48
+ sign_supported_for: assertBoolean(
49
+ selection.sign_supported_for,
50
+ "functional_dispatch.operation_selection.sign_supported_for"
51
+ )
52
+ },
53
+ content_digest_policy_source: "request_signing.covers_content_digest",
54
+ preserve_transport_auth: assertBoolean(r.preserve_transport_auth, "functional_dispatch.preserve_transport_auth"),
55
+ fresh_signature_per_dispatch: assertBoolean(
56
+ r.fresh_signature_per_dispatch,
57
+ "functional_dispatch.fresh_signature_per_dispatch"
58
+ ),
59
+ bootstrap_operations_unsigned: assertStringArray(
60
+ r.bootstrap_operations_unsigned,
61
+ "functional_dispatch.bootstrap_operations_unsigned"
62
+ ),
63
+ unavailable_behavior: "not_applicable"
64
+ };
65
+ }
18
66
  function parseHarnessMode(raw) {
19
67
  const s = assertString(raw, "harness_mode");
20
68
  if (s !== "black_box" && s !== "white_box") {
@@ -91,6 +139,16 @@ function assertNumber(v, where) {
91
139
  if (typeof v !== "number") throw new Error(`${where} must be number`);
92
140
  return v;
93
141
  }
142
+ function assertBoolean(v, where) {
143
+ if (typeof v !== "boolean") throw new Error(`${where} must be boolean`);
144
+ return v;
145
+ }
146
+ function assertStringArray(v, where) {
147
+ if (!Array.isArray(v) || v.some((item) => typeof item !== "string")) {
148
+ throw new Error(`${where} must be string[]`);
149
+ }
150
+ return v;
151
+ }
94
152
  export {
95
153
  loadSignedRequestsRunnerContract
96
154
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from '../compliance';\n\nexport interface RunnerSigningKey {\n keyid: string;\n alg: 'ed25519' | 'ecdsa-p256-sha256';\n}\n\nexport interface ReplayWindowContract {\n vector_id: string;\n black_box_behavior: 'repeat_request';\n max_interval_seconds: number;\n min_replay_ttl_seconds: number;\n}\n\nexport interface RevocationContract {\n vector_id: string;\n pre_revoked_keyid: string;\n}\n\nexport interface RateAbuseContract {\n vector_id: string;\n grading_target_per_keyid_cap_requests: number;\n production_min_per_keyid_cap_requests: number;\n window_seconds: number;\n}\n\nexport interface SignedRequestsRunnerContract {\n id: string;\n endpoint_scope: 'sandbox' | string;\n harness_mode: 'black_box' | 'white_box';\n runner_signing_keys: RunnerSigningKey[];\n stateful_vector_contract: {\n replay_window: ReplayWindowContract;\n revocation: RevocationContract;\n rate_abuse: RateAbuseContract;\n };\n}\n\nexport interface LoadTestKitOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Load and parse `test-kits/signed-requests-runner.yaml` from the compliance\n * cache. Returns undefined when the file is absent (upstream pre-adcp#2353\n * caches, or a sync in progress) — callers must decide how to degrade.\n */\nexport function loadSignedRequestsRunnerContract(\n options: LoadTestKitOptions = {}\n): SignedRequestsRunnerContract | undefined {\n const cacheDir = getComplianceCacheDir(options);\n const path = join(cacheDir, 'test-kits', 'signed-requests-runner.yaml');\n if (!existsSync(path)) return undefined;\n const raw = parse(readFileSync(path, 'utf-8')) as Record<string, unknown>;\n return {\n id: assertString(raw.id, 'id'),\n endpoint_scope: assertString(raw.endpoint_scope, 'endpoint_scope'),\n harness_mode: parseHarnessMode(raw.harness_mode),\n runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),\n stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract),\n };\n}\n\nfunction parseHarnessMode(raw: unknown): 'black_box' | 'white_box' {\n const s = assertString(raw, 'harness_mode');\n if (s !== 'black_box' && s !== 'white_box') {\n throw new Error(`test-kit harness_mode must be \"black_box\" or \"white_box\", got \"${s}\"`);\n }\n return s;\n}\n\nfunction parseSigningKeys(raw: unknown): RunnerSigningKey[] {\n if (!Array.isArray(raw)) throw new Error('runner_signing_keys must be an array');\n return raw.map((entry, i) => {\n const r = entry as Record<string, unknown>;\n const alg = assertString(r.alg, `runner_signing_keys[${i}].alg`);\n if (alg !== 'ed25519' && alg !== 'ecdsa-p256-sha256') {\n throw new Error(`runner_signing_keys[${i}].alg: unsupported \"${alg}\"`);\n }\n return { keyid: assertString(r.keyid, `runner_signing_keys[${i}].keyid`), alg };\n });\n}\n\nfunction parseStatefulContracts(raw: unknown): SignedRequestsRunnerContract['stateful_vector_contract'] {\n if (!raw || typeof raw !== 'object') {\n throw new Error('stateful_vector_contract block missing');\n }\n const r = raw as Record<string, unknown>;\n return {\n replay_window: parseReplay(r.replay_window),\n revocation: parseRevocation(r.revocation),\n rate_abuse: parseRateAbuse(r.rate_abuse),\n };\n}\n\nfunction parseReplay(raw: unknown): ReplayWindowContract {\n const r = asObject(raw, 'stateful_vector_contract.replay_window');\n const behavior = assertString(r.black_box_behavior, 'replay_window.black_box_behavior');\n if (behavior !== 'repeat_request') {\n throw new Error(`replay_window.black_box_behavior must be \"repeat_request\", got \"${behavior}\"`);\n }\n return {\n vector_id: assertString(r.vector_id, 'replay_window.vector_id'),\n black_box_behavior: 'repeat_request',\n max_interval_seconds: assertNumber(r.max_interval_seconds, 'replay_window.max_interval_seconds'),\n min_replay_ttl_seconds: assertNumber(r.min_replay_ttl_seconds, 'replay_window.min_replay_ttl_seconds'),\n };\n}\n\nfunction parseRevocation(raw: unknown): RevocationContract {\n const r = asObject(raw, 'stateful_vector_contract.revocation');\n return {\n vector_id: assertString(r.vector_id, 'revocation.vector_id'),\n pre_revoked_keyid: assertString(r.pre_revoked_keyid, 'revocation.pre_revoked_keyid'),\n };\n}\n\nfunction parseRateAbuse(raw: unknown): RateAbuseContract {\n const r = asObject(raw, 'stateful_vector_contract.rate_abuse');\n return {\n vector_id: assertString(r.vector_id, 'rate_abuse.vector_id'),\n grading_target_per_keyid_cap_requests: assertNumber(\n r.grading_target_per_keyid_cap_requests,\n 'rate_abuse.grading_target_per_keyid_cap_requests'\n ),\n production_min_per_keyid_cap_requests: assertNumber(\n r.production_min_per_keyid_cap_requests,\n 'rate_abuse.production_min_per_keyid_cap_requests'\n ),\n window_seconds: assertNumber(r.window_seconds, 'rate_abuse.window_seconds'),\n };\n}\n\nfunction asObject(raw: unknown, where: string): Record<string, unknown> {\n if (!raw || typeof raw !== 'object') throw new Error(`${where} missing or not an object`);\n return raw as Record<string, unknown>;\n}\n\nfunction assertString(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction assertNumber(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n"],"mappings":"AAAA,SAAS,YAAY,oBAAoB;AACzC,SAAS,YAAY;AACrB,SAAS,aAAa;AACtB,SAAS,6BAA6B;AAgD/B,SAAS,iCACd,UAA8B,CAAC,GACW;AAC1C,QAAM,WAAW,sBAAsB,OAAO;AAC9C,QAAM,OAAO,KAAK,UAAU,aAAa,6BAA6B;AACtE,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,QAAM,MAAM,MAAM,aAAa,MAAM,OAAO,CAAC;AAC7C,SAAO;AAAA,IACL,IAAI,aAAa,IAAI,IAAI,IAAI;AAAA,IAC7B,gBAAgB,aAAa,IAAI,gBAAgB,gBAAgB;AAAA,IACjE,cAAc,iBAAiB,IAAI,YAAY;AAAA,IAC/C,qBAAqB,iBAAiB,IAAI,mBAAmB;AAAA,IAC7D,0BAA0B,uBAAuB,IAAI,wBAAwB;AAAA,EAC/E;AACF;AAEA,SAAS,iBAAiB,KAAyC;AACjE,QAAM,IAAI,aAAa,KAAK,cAAc;AAC1C,MAAI,MAAM,eAAe,MAAM,aAAa;AAC1C,UAAM,IAAI,MAAM,kEAAkE,CAAC,GAAG;AAAA,EACxF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,KAAkC;AAC1D,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,OAAM,IAAI,MAAM,sCAAsC;AAC/E,SAAO,IAAI,IAAI,CAAC,OAAO,MAAM;AAC3B,UAAM,IAAI;AACV,UAAM,MAAM,aAAa,EAAE,KAAK,uBAAuB,CAAC,OAAO;AAC/D,QAAI,QAAQ,aAAa,QAAQ,qBAAqB;AACpD,YAAM,IAAI,MAAM,uBAAuB,CAAC,uBAAuB,GAAG,GAAG;AAAA,IACvE;AACA,WAAO,EAAE,OAAO,aAAa,EAAE,OAAO,uBAAuB,CAAC,SAAS,GAAG,IAAI;AAAA,EAChF,CAAC;AACH;AAEA,SAAS,uBAAuB,KAAwE;AACtG,MAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AACA,QAAM,IAAI;AACV,SAAO;AAAA,IACL,eAAe,YAAY,EAAE,aAAa;AAAA,IAC1C,YAAY,gBAAgB,EAAE,UAAU;AAAA,IACxC,YAAY,eAAe,EAAE,UAAU;AAAA,EACzC;AACF;AAEA,SAAS,YAAY,KAAoC;AACvD,QAAM,IAAI,SAAS,KAAK,wCAAwC;AAChE,QAAM,WAAW,aAAa,EAAE,oBAAoB,kCAAkC;AACtF,MAAI,aAAa,kBAAkB;AACjC,UAAM,IAAI,MAAM,mEAAmE,QAAQ,GAAG;AAAA,EAChG;AACA,SAAO;AAAA,IACL,WAAW,aAAa,EAAE,WAAW,yBAAyB;AAAA,IAC9D,oBAAoB;AAAA,IACpB,sBAAsB,aAAa,EAAE,sBAAsB,oCAAoC;AAAA,IAC/F,wBAAwB,aAAa,EAAE,wBAAwB,sCAAsC;AAAA,EACvG;AACF;AAEA,SAAS,gBAAgB,KAAkC;AACzD,QAAM,IAAI,SAAS,KAAK,qCAAqC;AAC7D,SAAO;AAAA,IACL,WAAW,aAAa,EAAE,WAAW,sBAAsB;AAAA,IAC3D,mBAAmB,aAAa,EAAE,mBAAmB,8BAA8B;AAAA,EACrF;AACF;AAEA,SAAS,eAAe,KAAiC;AACvD,QAAM,IAAI,SAAS,KAAK,qCAAqC;AAC7D,SAAO;AAAA,IACL,WAAW,aAAa,EAAE,WAAW,sBAAsB;AAAA,IAC3D,uCAAuC;AAAA,MACrC,EAAE;AAAA,MACF;AAAA,IACF;AAAA,IACA,uCAAuC;AAAA,MACrC,EAAE;AAAA,MACF;AAAA,IACF;AAAA,IACA,gBAAgB,aAAa,EAAE,gBAAgB,2BAA2B;AAAA,EAC5E;AACF;AAEA,SAAS,SAAS,KAAc,OAAwC;AACtE,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,OAAM,IAAI,MAAM,GAAG,KAAK,2BAA2B;AACxF,SAAO;AACT;AAEA,SAAS,aAAa,GAAY,OAAuB;AACvD,MAAI,OAAO,MAAM,SAAU,OAAM,IAAI,MAAM,GAAG,KAAK,iBAAiB;AACpE,SAAO;AACT;AAEA,SAAS,aAAa,GAAY,OAAuB;AACvD,MAAI,OAAO,MAAM,SAAU,OAAM,IAAI,MAAM,GAAG,KAAK,iBAAiB;AACpE,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/test-kit.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from '../compliance';\n\nexport interface RunnerSigningKey {\n keyid: string;\n alg: 'ed25519' | 'ecdsa-p256-sha256';\n}\n\nexport interface ReplayWindowContract {\n vector_id: string;\n black_box_behavior: 'repeat_request';\n max_interval_seconds: number;\n min_replay_ttl_seconds: number;\n}\n\nexport interface RevocationContract {\n vector_id: string;\n pre_revoked_keyid: string;\n}\n\nexport interface RateAbuseContract {\n vector_id: string;\n grading_target_per_keyid_cap_requests: number;\n production_min_per_keyid_cap_requests: number;\n window_seconds: number;\n}\n\nexport interface FunctionalDispatchContract {\n signing_keyid: string;\n signer_agent_url: string;\n operation_selection: {\n capability_path: 'request_signing';\n sign_required_for: boolean;\n sign_supported_for: boolean;\n };\n content_digest_policy_source: 'request_signing.covers_content_digest';\n preserve_transport_auth: boolean;\n fresh_signature_per_dispatch: boolean;\n bootstrap_operations_unsigned: string[];\n unavailable_behavior: 'not_applicable';\n}\n\nexport interface SignedRequestsRunnerContract {\n id: string;\n endpoint_scope: 'sandbox' | string;\n harness_mode: 'black_box' | 'white_box';\n runner_signing_keys: RunnerSigningKey[];\n functional_dispatch?: FunctionalDispatchContract;\n stateful_vector_contract: {\n replay_window: ReplayWindowContract;\n revocation: RevocationContract;\n rate_abuse: RateAbuseContract;\n };\n}\n\nexport interface LoadTestKitOptions {\n complianceDir?: string;\n version?: string;\n}\n\n/**\n * Load and parse `test-kits/signed-requests-runner.yaml` from the compliance\n * cache. Returns undefined when the file is absent (upstream pre-adcp#2353\n * caches, or a sync in progress) — callers must decide how to degrade.\n */\nexport function loadSignedRequestsRunnerContract(\n options: LoadTestKitOptions = {}\n): SignedRequestsRunnerContract | undefined {\n const cacheDir = getComplianceCacheDir(options);\n const path = join(cacheDir, 'test-kits', 'signed-requests-runner.yaml');\n if (!existsSync(path)) return undefined;\n const raw = parse(readFileSync(path, 'utf-8')) as Record<string, unknown>;\n const functionalDispatch = parseFunctionalDispatch(raw.functional_dispatch);\n return {\n id: assertString(raw.id, 'id'),\n endpoint_scope: assertString(raw.endpoint_scope, 'endpoint_scope'),\n harness_mode: parseHarnessMode(raw.harness_mode),\n runner_signing_keys: parseSigningKeys(raw.runner_signing_keys),\n ...(functionalDispatch && { functional_dispatch: functionalDispatch }),\n stateful_vector_contract: parseStatefulContracts(raw.stateful_vector_contract),\n };\n}\n\nfunction parseFunctionalDispatch(raw: unknown): FunctionalDispatchContract | undefined {\n if (raw === undefined) return undefined;\n const r = asObject(raw, 'functional_dispatch');\n const selection = asObject(r.operation_selection, 'functional_dispatch.operation_selection');\n const capabilityPath = assertString(\n selection.capability_path,\n 'functional_dispatch.operation_selection.capability_path'\n );\n if (capabilityPath !== 'request_signing') {\n throw new Error('functional_dispatch.operation_selection.capability_path must be \"request_signing\"');\n }\n const digestSource = assertString(r.content_digest_policy_source, 'functional_dispatch.content_digest_policy_source');\n if (digestSource !== 'request_signing.covers_content_digest') {\n throw new Error('functional_dispatch.content_digest_policy_source must be \"request_signing.covers_content_digest\"');\n }\n const unavailable = assertString(r.unavailable_behavior, 'functional_dispatch.unavailable_behavior');\n if (unavailable !== 'not_applicable') {\n throw new Error('functional_dispatch.unavailable_behavior must be \"not_applicable\"');\n }\n return {\n signing_keyid: assertString(r.signing_keyid, 'functional_dispatch.signing_keyid'),\n signer_agent_url: assertString(r.signer_agent_url, 'functional_dispatch.signer_agent_url'),\n operation_selection: {\n capability_path: 'request_signing',\n sign_required_for: assertBoolean(\n selection.sign_required_for,\n 'functional_dispatch.operation_selection.sign_required_for'\n ),\n sign_supported_for: assertBoolean(\n selection.sign_supported_for,\n 'functional_dispatch.operation_selection.sign_supported_for'\n ),\n },\n content_digest_policy_source: 'request_signing.covers_content_digest',\n preserve_transport_auth: assertBoolean(r.preserve_transport_auth, 'functional_dispatch.preserve_transport_auth'),\n fresh_signature_per_dispatch: assertBoolean(\n r.fresh_signature_per_dispatch,\n 'functional_dispatch.fresh_signature_per_dispatch'\n ),\n bootstrap_operations_unsigned: assertStringArray(\n r.bootstrap_operations_unsigned,\n 'functional_dispatch.bootstrap_operations_unsigned'\n ),\n unavailable_behavior: 'not_applicable',\n };\n}\n\nfunction parseHarnessMode(raw: unknown): 'black_box' | 'white_box' {\n const s = assertString(raw, 'harness_mode');\n if (s !== 'black_box' && s !== 'white_box') {\n throw new Error(`test-kit harness_mode must be \"black_box\" or \"white_box\", got \"${s}\"`);\n }\n return s;\n}\n\nfunction parseSigningKeys(raw: unknown): RunnerSigningKey[] {\n if (!Array.isArray(raw)) throw new Error('runner_signing_keys must be an array');\n return raw.map((entry, i) => {\n const r = entry as Record<string, unknown>;\n const alg = assertString(r.alg, `runner_signing_keys[${i}].alg`);\n if (alg !== 'ed25519' && alg !== 'ecdsa-p256-sha256') {\n throw new Error(`runner_signing_keys[${i}].alg: unsupported \"${alg}\"`);\n }\n return { keyid: assertString(r.keyid, `runner_signing_keys[${i}].keyid`), alg };\n });\n}\n\nfunction parseStatefulContracts(raw: unknown): SignedRequestsRunnerContract['stateful_vector_contract'] {\n if (!raw || typeof raw !== 'object') {\n throw new Error('stateful_vector_contract block missing');\n }\n const r = raw as Record<string, unknown>;\n return {\n replay_window: parseReplay(r.replay_window),\n revocation: parseRevocation(r.revocation),\n rate_abuse: parseRateAbuse(r.rate_abuse),\n };\n}\n\nfunction parseReplay(raw: unknown): ReplayWindowContract {\n const r = asObject(raw, 'stateful_vector_contract.replay_window');\n const behavior = assertString(r.black_box_behavior, 'replay_window.black_box_behavior');\n if (behavior !== 'repeat_request') {\n throw new Error(`replay_window.black_box_behavior must be \"repeat_request\", got \"${behavior}\"`);\n }\n return {\n vector_id: assertString(r.vector_id, 'replay_window.vector_id'),\n black_box_behavior: 'repeat_request',\n max_interval_seconds: assertNumber(r.max_interval_seconds, 'replay_window.max_interval_seconds'),\n min_replay_ttl_seconds: assertNumber(r.min_replay_ttl_seconds, 'replay_window.min_replay_ttl_seconds'),\n };\n}\n\nfunction parseRevocation(raw: unknown): RevocationContract {\n const r = asObject(raw, 'stateful_vector_contract.revocation');\n return {\n vector_id: assertString(r.vector_id, 'revocation.vector_id'),\n pre_revoked_keyid: assertString(r.pre_revoked_keyid, 'revocation.pre_revoked_keyid'),\n };\n}\n\nfunction parseRateAbuse(raw: unknown): RateAbuseContract {\n const r = asObject(raw, 'stateful_vector_contract.rate_abuse');\n return {\n vector_id: assertString(r.vector_id, 'rate_abuse.vector_id'),\n grading_target_per_keyid_cap_requests: assertNumber(\n r.grading_target_per_keyid_cap_requests,\n 'rate_abuse.grading_target_per_keyid_cap_requests'\n ),\n production_min_per_keyid_cap_requests: assertNumber(\n r.production_min_per_keyid_cap_requests,\n 'rate_abuse.production_min_per_keyid_cap_requests'\n ),\n window_seconds: assertNumber(r.window_seconds, 'rate_abuse.window_seconds'),\n };\n}\n\nfunction asObject(raw: unknown, where: string): Record<string, unknown> {\n if (!raw || typeof raw !== 'object') throw new Error(`${where} missing or not an object`);\n return raw as Record<string, unknown>;\n}\n\nfunction assertString(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction assertNumber(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n\nfunction assertBoolean(v: unknown, where: string): boolean {\n if (typeof v !== 'boolean') throw new Error(`${where} must be boolean`);\n return v;\n}\n\nfunction assertStringArray(v: unknown, where: string): string[] {\n if (!Array.isArray(v) || v.some(item => typeof item !== 'string')) {\n throw new Error(`${where} must be string[]`);\n }\n return v;\n}\n"],"mappings":"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","names":[]}
@@ -14,6 +14,8 @@ export interface LoadedVectors {
14
14
  sourceDir: string;
15
15
  }
16
16
  export declare function loadRequestSigningVectors(options?: LoadVectorsOptions): LoadedVectors;
17
+ /** Load only the shared signing keyset, without requiring the grader vectors. */
18
+ export declare function loadRequestSigningKeys(options?: LoadVectorsOptions): TestKeyset;
17
19
  /** Test-only: clear the memoization cache so a fresh cache path is reread. */
18
20
  export declare function __resetVectorCache(): void;
19
21
  export declare function findKey(keyset: TestKeyset, kid: string): TestKeypair;
@@ -14,6 +14,8 @@ export interface LoadedVectors {
14
14
  sourceDir: string;
15
15
  }
16
16
  export declare function loadRequestSigningVectors(options?: LoadVectorsOptions): LoadedVectors;
17
+ /** Load only the shared signing keyset, without requiring the grader vectors. */
18
+ export declare function loadRequestSigningKeys(options?: LoadVectorsOptions): TestKeyset;
17
19
  /** Test-only: clear the memoization cache so a fresh cache path is reread. */
18
20
  export declare function __resetVectorCache(): void;
19
21
  export declare function findKey(keyset: TestKeyset, kid: string): TestKeypair;
@@ -1 +1 @@
1
- {"version":3,"file":"vector-loader.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/vector-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAU,MAAM,SAAS,CAAC;AAE3G,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;QAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IACrF,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AA+BD,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa,CA6BzF;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAyLD,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAQpE"}
1
+ {"version":3,"file":"vector-loader.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/vector-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAU,MAAM,SAAS,CAAC;AAE3G,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;QAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IACrF,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AA+BD,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa,CA6BzF;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,kBAAuB,GAAG,UAAU,CAGnF;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAyLD,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAQpE"}
@@ -20,6 +20,7 @@ var vector_loader_exports = {};
20
20
  __export(vector_loader_exports, {
21
21
  __resetVectorCache: () => __resetVectorCache,
22
22
  findKey: () => findKey,
23
+ loadRequestSigningKeys: () => loadRequestSigningKeys,
23
24
  loadRequestSigningVectors: () => loadRequestSigningVectors
24
25
  });
25
26
  module.exports = __toCommonJS(vector_loader_exports);
@@ -67,12 +68,16 @@ function loadRequestSigningVectors(options = {}) {
67
68
  negative: loadDir((0, import_path.join)(profile32Dir, "negative"), parseNegative, "profile-3.2/negative/")
68
69
  }
69
70
  } : {},
70
- keys: loadKeys((0, import_path.join)(sourceDir, "keys.json")),
71
+ keys: loadRequestSigningKeys(options),
71
72
  sourceDir
72
73
  };
73
74
  VECTOR_CACHE.set(sourceDir, loaded);
74
75
  return loaded;
75
76
  }
77
+ function loadRequestSigningKeys(options = {}) {
78
+ const cacheDir = (0, import_compliance.getComplianceCacheDir)(options);
79
+ return loadKeys((0, import_path.join)(cacheDir, "test-vectors", "request-signing", "keys.json"));
80
+ }
76
81
  function __resetVectorCache() {
77
82
  VECTOR_CACHE.clear();
78
83
  }
@@ -268,6 +273,7 @@ function strArray(v, where) {
268
273
  0 && (module.exports = {
269
274
  __resetVectorCache,
270
275
  findKey,
276
+ loadRequestSigningKeys,
271
277
  loadRequestSigningVectors
272
278
  });
273
279
  //# sourceMappingURL=vector-loader.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/vector-loader.ts"],"sourcesContent":["import { existsSync, readFileSync, readdirSync } from 'fs';\nimport { basename, join } from 'path';\nimport { getComplianceCacheDir } from '../compliance';\nimport type { RequestSignatureErrorCode } from '../../../signing';\nimport { CONTRACT_IDS } from './types';\nimport type { ContractId, NegativeVector, PositiveVector, TestKeypair, TestKeyset, Vector } from './types';\n\nexport interface LoadVectorsOptions {\n complianceDir?: string;\n version?: string;\n}\n\nexport interface LoadedVectors {\n positive: PositiveVector[];\n negative: NegativeVector[];\n profiles: Record<string, { positive: PositiveVector[]; negative: NegativeVector[] }>;\n keys: TestKeyset;\n sourceDir: string;\n}\n\nconst ERROR_CODES: ReadonlySet<string> = new Set([\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_target_uri_malformed',\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]);\n\nconst CONTRACT_ID_SET: ReadonlySet<string> = new Set(CONTRACT_IDS);\n\n// Memoized per sourceDir — loading 28 JSON fixtures + keys.json on every\n// per-vector call in the runner path added up (~28 disk reads × 2-3 storyboard\n// resolve calls per CLI run). Invariant: the compliance cache is immutable\n// during a process lifetime — `npm run sync-schemas` runs before the process,\n// never concurrently. Cache key is the absolute cacheDir so env-var overrides\n// don't poison the entry.\nconst VECTOR_CACHE = new Map<string, LoadedVectors>();\n\nexport function loadRequestSigningVectors(options: LoadVectorsOptions = {}): LoadedVectors {\n const cacheDir = getComplianceCacheDir(options);\n const sourceDir = join(cacheDir, 'test-vectors', 'request-signing');\n const cached = VECTOR_CACHE.get(sourceDir);\n if (cached) return cached;\n\n if (!existsSync(sourceDir)) {\n throw new Error(\n `Request-signing vectors not found at ${sourceDir}. Run \\`npm run sync-schemas\\` or check your ADCP_COMPLIANCE_DIR.`\n );\n }\n\n const profile32Dir = join(sourceDir, 'profile-3.2');\n const loaded: LoadedVectors = {\n positive: loadDir(join(sourceDir, 'positive'), parsePositive),\n negative: loadDir(join(sourceDir, 'negative'), parseNegative),\n profiles: existsSync(profile32Dir)\n ? {\n '3.2': {\n positive: loadDir(join(profile32Dir, 'positive'), parsePositive, 'profile-3.2/positive/'),\n negative: loadDir(join(profile32Dir, 'negative'), parseNegative, 'profile-3.2/negative/'),\n },\n }\n : {},\n keys: loadKeys(join(sourceDir, 'keys.json')),\n sourceDir,\n };\n VECTOR_CACHE.set(sourceDir, loaded);\n return loaded;\n}\n\n/** Test-only: clear the memoization cache so a fresh cache path is reread. */\nexport function __resetVectorCache(): void {\n VECTOR_CACHE.clear();\n}\n\nfunction loadDir<T extends Vector>(dir: string, parse: (id: string, raw: unknown) => T, idPrefix = ''): T[] {\n if (!existsSync(dir)) {\n throw new Error(`Vector directory missing: ${dir}`);\n }\n const files = readdirSync(dir)\n .filter(f => f.endsWith('.json'))\n .sort();\n return files.map(f => {\n const raw = JSON.parse(readFileSync(join(dir, f), 'utf-8'));\n return parse(`${idPrefix}${vectorIdFromFilename(f)}`, raw);\n });\n}\n\nfunction vectorIdFromFilename(file: string): string {\n return basename(file, '.json');\n}\n\nfunction parsePositive(id: string, raw: unknown): PositiveVector {\n const r = raw as Record<string, unknown>;\n assertSuccess(id, r, true);\n const { jwks_ref, jwks_override } = parseJwksSelector(id, r);\n return {\n kind: 'positive',\n id,\n name: str(r.name, `${id}.name`),\n signing_profile_version: optionalSigningProfileVersion(r),\n reference_now: num(r.reference_now, `${id}.reference_now`),\n request: parseRequest(id, r.request),\n verifier_capability: parseCapability(id, r.verifier_capability),\n jwks_ref,\n jwks_override,\n expected_signature_base: typeof r.expected_signature_base === 'string' ? r.expected_signature_base : undefined,\n spec_reference: typeof r.spec_reference === 'string' ? r.spec_reference : undefined,\n };\n}\n\nfunction parseNegative(id: string, raw: unknown): NegativeVector {\n const r = raw as Record<string, unknown>;\n assertSuccess(id, r, false);\n const outcome = r.expected_outcome as Record<string, unknown>;\n const errorCode = str(outcome.error_code, `${id}.expected_outcome.error_code`);\n if (!ERROR_CODES.has(errorCode)) {\n throw new Error(`${id}: unknown expected_outcome.error_code \"${errorCode}\" (spec drift?)`);\n }\n const failedStep = outcome.failed_step;\n if (typeof failedStep !== 'number' && typeof failedStep !== 'string') {\n throw new Error(`${id}: expected_outcome.failed_step must be number or string`);\n }\n let contract: ContractId | undefined;\n if (r.requires_contract !== undefined) {\n const c = str(r.requires_contract, `${id}.requires_contract`);\n if (!CONTRACT_ID_SET.has(c)) {\n throw new Error(`${id}: unknown requires_contract \"${c}\" (spec drift?)`);\n }\n contract = c as ContractId;\n }\n const { jwks_ref, jwks_override } = parseJwksSelector(id, r);\n return {\n kind: 'negative',\n id,\n name: str(r.name, `${id}.name`),\n signing_profile_version: optionalSigningProfileVersion(r),\n reference_now: num(r.reference_now, `${id}.reference_now`),\n request: parseRequest(id, r.request),\n verifier_capability: parseCapability(id, r.verifier_capability),\n jwks_ref,\n jwks_override,\n expected_error_code: errorCode as RequestSignatureErrorCode,\n expected_failed_step: failedStep,\n requires_contract: contract,\n spec_reference: typeof r.spec_reference === 'string' ? r.spec_reference : undefined,\n };\n}\n\nfunction optionalSigningProfileVersion(vector: Record<string, unknown>): string {\n // Older cached bundles predate the explicit marker; every root vector in\n // those bundles exercises the legacy 3.1 binary profile.\n return typeof vector.signing_profile_version === 'string' ? vector.signing_profile_version : '3.1';\n}\n\nfunction parseJwksSelector(\n id: string,\n r: Record<string, unknown>\n): { jwks_ref?: string[]; jwks_override?: { keys: Array<Record<string, unknown>> } } {\n const hasRef = r.jwks_ref !== undefined;\n const hasOverride = r.jwks_override !== undefined;\n if (hasRef && hasOverride) {\n throw new Error(`${id}: jwks_ref and jwks_override are mutually exclusive`);\n }\n if (!hasRef && !hasOverride) {\n throw new Error(`${id}: must declare either jwks_ref or jwks_override`);\n }\n if (hasOverride) {\n const override = r.jwks_override as Record<string, unknown>;\n const keys = override.keys;\n if (!Array.isArray(keys) || keys.length === 0) {\n throw new Error(`${id}.jwks_override.keys must be a non-empty array`);\n }\n for (const k of keys) {\n if (!k || typeof k !== 'object') {\n throw new Error(`${id}.jwks_override.keys[] entries must be objects`);\n }\n }\n return { jwks_override: { keys: keys as Array<Record<string, unknown>> } };\n }\n return { jwks_ref: strArray(r.jwks_ref, `${id}.jwks_ref`) };\n}\n\nfunction assertSuccess(id: string, vector: Record<string, unknown>, expected: boolean): void {\n const outcome = vector.expected_outcome as Record<string, unknown> | undefined;\n if (!outcome || outcome.success !== expected) {\n throw new Error(\n `${id}: expected_outcome.success must be ${expected} for ${expected ? 'positive' : 'negative'} vector`\n );\n }\n}\n\nfunction parseRequest(id: string, raw: unknown): PositiveVector['request'] {\n const r = raw as Record<string, unknown> | undefined;\n if (!r) throw new Error(`${id}.request missing`);\n const headers = r.headers as Record<string, string> | undefined;\n if (!headers) throw new Error(`${id}.request.headers missing`);\n return {\n method: str(r.method, `${id}.request.method`),\n url: str(r.url, `${id}.request.url`),\n headers: { ...headers },\n body: typeof r.body === 'string' ? r.body : undefined,\n };\n}\n\nfunction parseCapability(id: string, raw: unknown): PositiveVector['verifier_capability'] {\n const r = raw as Record<string, unknown> | undefined;\n if (!r) throw new Error(`${id}.verifier_capability missing`);\n const digest = str(r.covers_content_digest, `${id}.verifier_capability.covers_content_digest`);\n if (digest !== 'required' && digest !== 'forbidden' && digest !== 'either') {\n throw new Error(`${id}: invalid covers_content_digest \"${digest}\"`);\n }\n return {\n supported: bool(r.supported, `${id}.verifier_capability.supported`),\n covers_content_digest: digest,\n required_for: strArray(r.required_for, `${id}.verifier_capability.required_for`),\n supported_for: Array.isArray(r.supported_for) ? (r.supported_for as string[]) : undefined,\n protocol_methods_supported_for: Array.isArray(r.protocol_methods_supported_for)\n ? (r.protocol_methods_supported_for as string[])\n : undefined,\n protocol_methods_required_for: Array.isArray(r.protocol_methods_required_for)\n ? (r.protocol_methods_required_for as string[])\n : undefined,\n };\n}\n\nfunction loadKeys(keysPath: string): TestKeyset {\n if (!existsSync(keysPath)) {\n throw new Error(`keys.json missing at ${keysPath}`);\n }\n const raw = JSON.parse(readFileSync(keysPath, 'utf-8')) as { keys?: unknown };\n if (!Array.isArray(raw.keys)) {\n throw new Error(`keys.json must contain a \"keys\" array`);\n }\n return { keys: raw.keys.map((k, i) => parseKey(i, k)) };\n}\n\nfunction parseKey(index: number, raw: unknown): TestKeypair {\n const r = raw as Record<string, unknown>;\n const where = `keys.json[${index}]`;\n const privateD = r._private_d_for_test_only;\n if (typeof privateD !== 'string' || privateD.length === 0) {\n throw new Error(`${where}._private_d_for_test_only missing (required for dynamic signing)`);\n }\n return {\n kid: str(r.kid, `${where}.kid`),\n kty: str(r.kty, `${where}.kty`),\n crv: typeof r.crv === 'string' ? r.crv : undefined,\n alg: typeof r.alg === 'string' ? r.alg : undefined,\n use: typeof r.use === 'string' ? r.use : undefined,\n key_ops: Array.isArray(r.key_ops) ? (r.key_ops as string[]) : undefined,\n adcp_use: typeof r.adcp_use === 'string' ? r.adcp_use : undefined,\n x: typeof r.x === 'string' ? r.x : undefined,\n y: typeof r.y === 'string' ? r.y : undefined,\n private_d: privateD,\n };\n}\n\nexport function findKey(keyset: TestKeyset, kid: string): TestKeypair {\n const match = keyset.keys.find(k => k.kid === kid);\n if (!match) {\n throw new Error(\n `No test keypair with kid=\"${kid}\" in keys.json (available: ${keyset.keys.map(k => k.kid).join(', ')})`\n );\n }\n return match;\n}\n\nfunction str(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction num(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n\nfunction bool(v: unknown, where: string): boolean {\n if (typeof v !== 'boolean') throw new Error(`${where} must be boolean`);\n return v;\n}\n\nfunction strArray(v: unknown, where: string): string[] {\n if (!Array.isArray(v) || v.some(item => typeof item !== 'string')) {\n throw new Error(`${where} must be string[]`);\n }\n return v as string[];\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/vector-loader.ts"],"sourcesContent":["import { existsSync, readFileSync, readdirSync } from 'fs';\nimport { basename, join } from 'path';\nimport { getComplianceCacheDir } from '../compliance';\nimport type { RequestSignatureErrorCode } from '../../../signing';\nimport { CONTRACT_IDS } from './types';\nimport type { ContractId, NegativeVector, PositiveVector, TestKeypair, TestKeyset, Vector } from './types';\n\nexport interface LoadVectorsOptions {\n complianceDir?: string;\n version?: string;\n}\n\nexport interface LoadedVectors {\n positive: PositiveVector[];\n negative: NegativeVector[];\n profiles: Record<string, { positive: PositiveVector[]; negative: NegativeVector[] }>;\n keys: TestKeyset;\n sourceDir: string;\n}\n\nconst ERROR_CODES: ReadonlySet<string> = new Set([\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_target_uri_malformed',\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]);\n\nconst CONTRACT_ID_SET: ReadonlySet<string> = new Set(CONTRACT_IDS);\n\n// Memoized per sourceDir — loading 28 JSON fixtures + keys.json on every\n// per-vector call in the runner path added up (~28 disk reads × 2-3 storyboard\n// resolve calls per CLI run). Invariant: the compliance cache is immutable\n// during a process lifetime — `npm run sync-schemas` runs before the process,\n// never concurrently. Cache key is the absolute cacheDir so env-var overrides\n// don't poison the entry.\nconst VECTOR_CACHE = new Map<string, LoadedVectors>();\n\nexport function loadRequestSigningVectors(options: LoadVectorsOptions = {}): LoadedVectors {\n const cacheDir = getComplianceCacheDir(options);\n const sourceDir = join(cacheDir, 'test-vectors', 'request-signing');\n const cached = VECTOR_CACHE.get(sourceDir);\n if (cached) return cached;\n\n if (!existsSync(sourceDir)) {\n throw new Error(\n `Request-signing vectors not found at ${sourceDir}. Run \\`npm run sync-schemas\\` or check your ADCP_COMPLIANCE_DIR.`\n );\n }\n\n const profile32Dir = join(sourceDir, 'profile-3.2');\n const loaded: LoadedVectors = {\n positive: loadDir(join(sourceDir, 'positive'), parsePositive),\n negative: loadDir(join(sourceDir, 'negative'), parseNegative),\n profiles: existsSync(profile32Dir)\n ? {\n '3.2': {\n positive: loadDir(join(profile32Dir, 'positive'), parsePositive, 'profile-3.2/positive/'),\n negative: loadDir(join(profile32Dir, 'negative'), parseNegative, 'profile-3.2/negative/'),\n },\n }\n : {},\n keys: loadRequestSigningKeys(options),\n sourceDir,\n };\n VECTOR_CACHE.set(sourceDir, loaded);\n return loaded;\n}\n\n/** Load only the shared signing keyset, without requiring the grader vectors. */\nexport function loadRequestSigningKeys(options: LoadVectorsOptions = {}): TestKeyset {\n const cacheDir = getComplianceCacheDir(options);\n return loadKeys(join(cacheDir, 'test-vectors', 'request-signing', 'keys.json'));\n}\n\n/** Test-only: clear the memoization cache so a fresh cache path is reread. */\nexport function __resetVectorCache(): void {\n VECTOR_CACHE.clear();\n}\n\nfunction loadDir<T extends Vector>(dir: string, parse: (id: string, raw: unknown) => T, idPrefix = ''): T[] {\n if (!existsSync(dir)) {\n throw new Error(`Vector directory missing: ${dir}`);\n }\n const files = readdirSync(dir)\n .filter(f => f.endsWith('.json'))\n .sort();\n return files.map(f => {\n const raw = JSON.parse(readFileSync(join(dir, f), 'utf-8'));\n return parse(`${idPrefix}${vectorIdFromFilename(f)}`, raw);\n });\n}\n\nfunction vectorIdFromFilename(file: string): string {\n return basename(file, '.json');\n}\n\nfunction parsePositive(id: string, raw: unknown): PositiveVector {\n const r = raw as Record<string, unknown>;\n assertSuccess(id, r, true);\n const { jwks_ref, jwks_override } = parseJwksSelector(id, r);\n return {\n kind: 'positive',\n id,\n name: str(r.name, `${id}.name`),\n signing_profile_version: optionalSigningProfileVersion(r),\n reference_now: num(r.reference_now, `${id}.reference_now`),\n request: parseRequest(id, r.request),\n verifier_capability: parseCapability(id, r.verifier_capability),\n jwks_ref,\n jwks_override,\n expected_signature_base: typeof r.expected_signature_base === 'string' ? r.expected_signature_base : undefined,\n spec_reference: typeof r.spec_reference === 'string' ? r.spec_reference : undefined,\n };\n}\n\nfunction parseNegative(id: string, raw: unknown): NegativeVector {\n const r = raw as Record<string, unknown>;\n assertSuccess(id, r, false);\n const outcome = r.expected_outcome as Record<string, unknown>;\n const errorCode = str(outcome.error_code, `${id}.expected_outcome.error_code`);\n if (!ERROR_CODES.has(errorCode)) {\n throw new Error(`${id}: unknown expected_outcome.error_code \"${errorCode}\" (spec drift?)`);\n }\n const failedStep = outcome.failed_step;\n if (typeof failedStep !== 'number' && typeof failedStep !== 'string') {\n throw new Error(`${id}: expected_outcome.failed_step must be number or string`);\n }\n let contract: ContractId | undefined;\n if (r.requires_contract !== undefined) {\n const c = str(r.requires_contract, `${id}.requires_contract`);\n if (!CONTRACT_ID_SET.has(c)) {\n throw new Error(`${id}: unknown requires_contract \"${c}\" (spec drift?)`);\n }\n contract = c as ContractId;\n }\n const { jwks_ref, jwks_override } = parseJwksSelector(id, r);\n return {\n kind: 'negative',\n id,\n name: str(r.name, `${id}.name`),\n signing_profile_version: optionalSigningProfileVersion(r),\n reference_now: num(r.reference_now, `${id}.reference_now`),\n request: parseRequest(id, r.request),\n verifier_capability: parseCapability(id, r.verifier_capability),\n jwks_ref,\n jwks_override,\n expected_error_code: errorCode as RequestSignatureErrorCode,\n expected_failed_step: failedStep,\n requires_contract: contract,\n spec_reference: typeof r.spec_reference === 'string' ? r.spec_reference : undefined,\n };\n}\n\nfunction optionalSigningProfileVersion(vector: Record<string, unknown>): string {\n // Older cached bundles predate the explicit marker; every root vector in\n // those bundles exercises the legacy 3.1 binary profile.\n return typeof vector.signing_profile_version === 'string' ? vector.signing_profile_version : '3.1';\n}\n\nfunction parseJwksSelector(\n id: string,\n r: Record<string, unknown>\n): { jwks_ref?: string[]; jwks_override?: { keys: Array<Record<string, unknown>> } } {\n const hasRef = r.jwks_ref !== undefined;\n const hasOverride = r.jwks_override !== undefined;\n if (hasRef && hasOverride) {\n throw new Error(`${id}: jwks_ref and jwks_override are mutually exclusive`);\n }\n if (!hasRef && !hasOverride) {\n throw new Error(`${id}: must declare either jwks_ref or jwks_override`);\n }\n if (hasOverride) {\n const override = r.jwks_override as Record<string, unknown>;\n const keys = override.keys;\n if (!Array.isArray(keys) || keys.length === 0) {\n throw new Error(`${id}.jwks_override.keys must be a non-empty array`);\n }\n for (const k of keys) {\n if (!k || typeof k !== 'object') {\n throw new Error(`${id}.jwks_override.keys[] entries must be objects`);\n }\n }\n return { jwks_override: { keys: keys as Array<Record<string, unknown>> } };\n }\n return { jwks_ref: strArray(r.jwks_ref, `${id}.jwks_ref`) };\n}\n\nfunction assertSuccess(id: string, vector: Record<string, unknown>, expected: boolean): void {\n const outcome = vector.expected_outcome as Record<string, unknown> | undefined;\n if (!outcome || outcome.success !== expected) {\n throw new Error(\n `${id}: expected_outcome.success must be ${expected} for ${expected ? 'positive' : 'negative'} vector`\n );\n }\n}\n\nfunction parseRequest(id: string, raw: unknown): PositiveVector['request'] {\n const r = raw as Record<string, unknown> | undefined;\n if (!r) throw new Error(`${id}.request missing`);\n const headers = r.headers as Record<string, string> | undefined;\n if (!headers) throw new Error(`${id}.request.headers missing`);\n return {\n method: str(r.method, `${id}.request.method`),\n url: str(r.url, `${id}.request.url`),\n headers: { ...headers },\n body: typeof r.body === 'string' ? r.body : undefined,\n };\n}\n\nfunction parseCapability(id: string, raw: unknown): PositiveVector['verifier_capability'] {\n const r = raw as Record<string, unknown> | undefined;\n if (!r) throw new Error(`${id}.verifier_capability missing`);\n const digest = str(r.covers_content_digest, `${id}.verifier_capability.covers_content_digest`);\n if (digest !== 'required' && digest !== 'forbidden' && digest !== 'either') {\n throw new Error(`${id}: invalid covers_content_digest \"${digest}\"`);\n }\n return {\n supported: bool(r.supported, `${id}.verifier_capability.supported`),\n covers_content_digest: digest,\n required_for: strArray(r.required_for, `${id}.verifier_capability.required_for`),\n supported_for: Array.isArray(r.supported_for) ? (r.supported_for as string[]) : undefined,\n protocol_methods_supported_for: Array.isArray(r.protocol_methods_supported_for)\n ? (r.protocol_methods_supported_for as string[])\n : undefined,\n protocol_methods_required_for: Array.isArray(r.protocol_methods_required_for)\n ? (r.protocol_methods_required_for as string[])\n : undefined,\n };\n}\n\nfunction loadKeys(keysPath: string): TestKeyset {\n if (!existsSync(keysPath)) {\n throw new Error(`keys.json missing at ${keysPath}`);\n }\n const raw = JSON.parse(readFileSync(keysPath, 'utf-8')) as { keys?: unknown };\n if (!Array.isArray(raw.keys)) {\n throw new Error(`keys.json must contain a \"keys\" array`);\n }\n return { keys: raw.keys.map((k, i) => parseKey(i, k)) };\n}\n\nfunction parseKey(index: number, raw: unknown): TestKeypair {\n const r = raw as Record<string, unknown>;\n const where = `keys.json[${index}]`;\n const privateD = r._private_d_for_test_only;\n if (typeof privateD !== 'string' || privateD.length === 0) {\n throw new Error(`${where}._private_d_for_test_only missing (required for dynamic signing)`);\n }\n return {\n kid: str(r.kid, `${where}.kid`),\n kty: str(r.kty, `${where}.kty`),\n crv: typeof r.crv === 'string' ? r.crv : undefined,\n alg: typeof r.alg === 'string' ? r.alg : undefined,\n use: typeof r.use === 'string' ? r.use : undefined,\n key_ops: Array.isArray(r.key_ops) ? (r.key_ops as string[]) : undefined,\n adcp_use: typeof r.adcp_use === 'string' ? r.adcp_use : undefined,\n x: typeof r.x === 'string' ? r.x : undefined,\n y: typeof r.y === 'string' ? r.y : undefined,\n private_d: privateD,\n };\n}\n\nexport function findKey(keyset: TestKeyset, kid: string): TestKeypair {\n const match = keyset.keys.find(k => k.kid === kid);\n if (!match) {\n throw new Error(\n `No test keypair with kid=\"${kid}\" in keys.json (available: ${keyset.keys.map(k => k.kid).join(', ')})`\n );\n }\n return match;\n}\n\nfunction str(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction num(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n\nfunction bool(v: unknown, where: string): boolean {\n if (typeof v !== 'boolean') throw new Error(`${where} must be boolean`);\n return v;\n}\n\nfunction strArray(v: unknown, where: string): string[] {\n if (!Array.isArray(v) || v.some(item => typeof item !== 'string')) {\n throw new Error(`${where} must be string[]`);\n }\n return v as string[];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAsD;AACtD,kBAA+B;AAC/B,wBAAsC;AAEtC,mBAA6B;AAgB7B,MAAM,cAAmC,oBAAI,IAAI;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,MAAM,kBAAuC,IAAI,IAAI,yBAAY;AAQjE,MAAM,eAAe,oBAAI,IAA2B;AAE7C,SAAS,0BAA0B,UAA8B,CAAC,GAAkB;AACzF,QAAM,eAAW,yCAAsB,OAAO;AAC9C,QAAM,gBAAY,kBAAK,UAAU,gBAAgB,iBAAiB;AAClE,QAAM,SAAS,aAAa,IAAI,SAAS;AACzC,MAAI,OAAQ,QAAO;AAEnB,MAAI,KAAC,sBAAW,SAAS,GAAG;AAC1B,UAAM,IAAI;AAAA,MACR,wCAAwC,SAAS;AAAA,IACnD;AAAA,EACF;AAEA,QAAM,mBAAe,kBAAK,WAAW,aAAa;AAClD,QAAM,SAAwB;AAAA,IAC5B,UAAU,YAAQ,kBAAK,WAAW,UAAU,GAAG,aAAa;AAAA,IAC5D,UAAU,YAAQ,kBAAK,WAAW,UAAU,GAAG,aAAa;AAAA,IAC5D,cAAU,sBAAW,YAAY,IAC7B;AAAA,MACE,OAAO;AAAA,QACL,UAAU,YAAQ,kBAAK,cAAc,UAAU,GAAG,eAAe,uBAAuB;AAAA,QACxF,UAAU,YAAQ,kBAAK,cAAc,UAAU,GAAG,eAAe,uBAAuB;AAAA,MAC1F;AAAA,IACF,IACA,CAAC;AAAA,IACL,MAAM,uBAAuB,OAAO;AAAA,IACpC;AAAA,EACF;AACA,eAAa,IAAI,WAAW,MAAM;AAClC,SAAO;AACT;AAGO,SAAS,uBAAuB,UAA8B,CAAC,GAAe;AACnF,QAAM,eAAW,yCAAsB,OAAO;AAC9C,SAAO,aAAS,kBAAK,UAAU,gBAAgB,mBAAmB,WAAW,CAAC;AAChF;AAGO,SAAS,qBAA2B;AACzC,eAAa,MAAM;AACrB;AAEA,SAAS,QAA0B,KAAa,OAAwC,WAAW,IAAS;AAC1G,MAAI,KAAC,sBAAW,GAAG,GAAG;AACpB,UAAM,IAAI,MAAM,6BAA6B,GAAG,EAAE;AAAA,EACpD;AACA,QAAM,YAAQ,uBAAY,GAAG,EAC1B,OAAO,OAAK,EAAE,SAAS,OAAO,CAAC,EAC/B,KAAK;AACR,SAAO,MAAM,IAAI,OAAK;AACpB,UAAM,MAAM,KAAK,UAAM,4BAAa,kBAAK,KAAK,CAAC,GAAG,OAAO,CAAC;AAC1D,WAAO,MAAM,GAAG,QAAQ,GAAG,qBAAqB,CAAC,CAAC,IAAI,GAAG;AAAA,EAC3D,CAAC;AACH;AAEA,SAAS,qBAAqB,MAAsB;AAClD,aAAO,sBAAS,MAAM,OAAO;AAC/B;AAEA,SAAS,cAAc,IAAY,KAA8B;AAC/D,QAAM,IAAI;AACV,gBAAc,IAAI,GAAG,IAAI;AACzB,QAAM,EAAE,UAAU,cAAc,IAAI,kBAAkB,IAAI,CAAC;AAC3D,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,MAAM,IAAI,EAAE,MAAM,GAAG,EAAE,OAAO;AAAA,IAC9B,yBAAyB,8BAA8B,CAAC;AAAA,IACxD,eAAe,IAAI,EAAE,eAAe,GAAG,EAAE,gBAAgB;AAAA,IACzD,SAAS,aAAa,IAAI,EAAE,OAAO;AAAA,IACnC,qBAAqB,gBAAgB,IAAI,EAAE,mBAAmB;AAAA,IAC9D;AAAA,IACA;AAAA,IACA,yBAAyB,OAAO,EAAE,4BAA4B,WAAW,EAAE,0BAA0B;AAAA,IACrG,gBAAgB,OAAO,EAAE,mBAAmB,WAAW,EAAE,iBAAiB;AAAA,EAC5E;AACF;AAEA,SAAS,cAAc,IAAY,KAA8B;AAC/D,QAAM,IAAI;AACV,gBAAc,IAAI,GAAG,KAAK;AAC1B,QAAM,UAAU,EAAE;AAClB,QAAM,YAAY,IAAI,QAAQ,YAAY,GAAG,EAAE,8BAA8B;AAC7E,MAAI,CAAC,YAAY,IAAI,SAAS,GAAG;AAC/B,UAAM,IAAI,MAAM,GAAG,EAAE,0CAA0C,SAAS,iBAAiB;AAAA,EAC3F;AACA,QAAM,aAAa,QAAQ;AAC3B,MAAI,OAAO,eAAe,YAAY,OAAO,eAAe,UAAU;AACpE,UAAM,IAAI,MAAM,GAAG,EAAE,yDAAyD;AAAA,EAChF;AACA,MAAI;AACJ,MAAI,EAAE,sBAAsB,QAAW;AACrC,UAAM,IAAI,IAAI,EAAE,mBAAmB,GAAG,EAAE,oBAAoB;AAC5D,QAAI,CAAC,gBAAgB,IAAI,CAAC,GAAG;AAC3B,YAAM,IAAI,MAAM,GAAG,EAAE,gCAAgC,CAAC,iBAAiB;AAAA,IACzE;AACA,eAAW;AAAA,EACb;AACA,QAAM,EAAE,UAAU,cAAc,IAAI,kBAAkB,IAAI,CAAC;AAC3D,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,MAAM,IAAI,EAAE,MAAM,GAAG,EAAE,OAAO;AAAA,IAC9B,yBAAyB,8BAA8B,CAAC;AAAA,IACxD,eAAe,IAAI,EAAE,eAAe,GAAG,EAAE,gBAAgB;AAAA,IACzD,SAAS,aAAa,IAAI,EAAE,OAAO;AAAA,IACnC,qBAAqB,gBAAgB,IAAI,EAAE,mBAAmB;AAAA,IAC9D;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA,IACrB,sBAAsB;AAAA,IACtB,mBAAmB;AAAA,IACnB,gBAAgB,OAAO,EAAE,mBAAmB,WAAW,EAAE,iBAAiB;AAAA,EAC5E;AACF;AAEA,SAAS,8BAA8B,QAAyC;AAG9E,SAAO,OAAO,OAAO,4BAA4B,WAAW,OAAO,0BAA0B;AAC/F;AAEA,SAAS,kBACP,IACA,GACmF;AACnF,QAAM,SAAS,EAAE,aAAa;AAC9B,QAAM,cAAc,EAAE,kBAAkB;AACxC,MAAI,UAAU,aAAa;AACzB,UAAM,IAAI,MAAM,GAAG,EAAE,qDAAqD;AAAA,EAC5E;AACA,MAAI,CAAC,UAAU,CAAC,aAAa;AAC3B,UAAM,IAAI,MAAM,GAAG,EAAE,iDAAiD;AAAA,EACxE;AACA,MAAI,aAAa;AACf,UAAM,WAAW,EAAE;AACnB,UAAM,OAAO,SAAS;AACtB,QAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,WAAW,GAAG;AAC7C,YAAM,IAAI,MAAM,GAAG,EAAE,+CAA+C;AAAA,IACtE;AACA,eAAW,KAAK,MAAM;AACpB,UAAI,CAAC,KAAK,OAAO,MAAM,UAAU;AAC/B,cAAM,IAAI,MAAM,GAAG,EAAE,+CAA+C;AAAA,MACtE;AAAA,IACF;AACA,WAAO,EAAE,eAAe,EAAE,KAA6C,EAAE;AAAA,EAC3E;AACA,SAAO,EAAE,UAAU,SAAS,EAAE,UAAU,GAAG,EAAE,WAAW,EAAE;AAC5D;AAEA,SAAS,cAAc,IAAY,QAAiC,UAAyB;AAC3F,QAAM,UAAU,OAAO;AACvB,MAAI,CAAC,WAAW,QAAQ,YAAY,UAAU;AAC5C,UAAM,IAAI;AAAA,MACR,GAAG,EAAE,sCAAsC,QAAQ,QAAQ,WAAW,aAAa,UAAU;AAAA,IAC/F;AAAA,EACF;AACF;AAEA,SAAS,aAAa,IAAY,KAAyC;AACzE,QAAM,IAAI;AACV,MAAI,CAAC,EAAG,OAAM,IAAI,MAAM,GAAG,EAAE,kBAAkB;AAC/C,QAAM,UAAU,EAAE;AAClB,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,GAAG,EAAE,0BAA0B;AAC7D,SAAO;AAAA,IACL,QAAQ,IAAI,EAAE,QAAQ,GAAG,EAAE,iBAAiB;AAAA,IAC5C,KAAK,IAAI,EAAE,KAAK,GAAG,EAAE,cAAc;AAAA,IACnC,SAAS,EAAE,GAAG,QAAQ;AAAA,IACtB,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AAAA,EAC9C;AACF;AAEA,SAAS,gBAAgB,IAAY,KAAqD;AACxF,QAAM,IAAI;AACV,MAAI,CAAC,EAAG,OAAM,IAAI,MAAM,GAAG,EAAE,8BAA8B;AAC3D,QAAM,SAAS,IAAI,EAAE,uBAAuB,GAAG,EAAE,4CAA4C;AAC7F,MAAI,WAAW,cAAc,WAAW,eAAe,WAAW,UAAU;AAC1E,UAAM,IAAI,MAAM,GAAG,EAAE,oCAAoC,MAAM,GAAG;AAAA,EACpE;AACA,SAAO;AAAA,IACL,WAAW,KAAK,EAAE,WAAW,GAAG,EAAE,gCAAgC;AAAA,IAClE,uBAAuB;AAAA,IACvB,cAAc,SAAS,EAAE,cAAc,GAAG,EAAE,mCAAmC;AAAA,IAC/E,eAAe,MAAM,QAAQ,EAAE,aAAa,IAAK,EAAE,gBAA6B;AAAA,IAChF,gCAAgC,MAAM,QAAQ,EAAE,8BAA8B,IACzE,EAAE,iCACH;AAAA,IACJ,+BAA+B,MAAM,QAAQ,EAAE,6BAA6B,IACvE,EAAE,gCACH;AAAA,EACN;AACF;AAEA,SAAS,SAAS,UAA8B;AAC9C,MAAI,KAAC,sBAAW,QAAQ,GAAG;AACzB,UAAM,IAAI,MAAM,wBAAwB,QAAQ,EAAE;AAAA,EACpD;AACA,QAAM,MAAM,KAAK,UAAM,wBAAa,UAAU,OAAO,CAAC;AACtD,MAAI,CAAC,MAAM,QAAQ,IAAI,IAAI,GAAG;AAC5B,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AACA,SAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,GAAG,MAAM,SAAS,GAAG,CAAC,CAAC,EAAE;AACxD;AAEA,SAAS,SAAS,OAAe,KAA2B;AAC1D,QAAM,IAAI;AACV,QAAM,QAAQ,aAAa,KAAK;AAChC,QAAM,WAAW,EAAE;AACnB,MAAI,OAAO,aAAa,YAAY,SAAS,WAAW,GAAG;AACzD,UAAM,IAAI,MAAM,GAAG,KAAK,kEAAkE;AAAA,EAC5F;AACA,SAAO;AAAA,IACL,KAAK,IAAI,EAAE,KAAK,GAAG,KAAK,MAAM;AAAA,IAC9B,KAAK,IAAI,EAAE,KAAK,GAAG,KAAK,MAAM;AAAA,IAC9B,KAAK,OAAO,EAAE,QAAQ,WAAW,EAAE,MAAM;AAAA,IACzC,KAAK,OAAO,EAAE,QAAQ,WAAW,EAAE,MAAM;AAAA,IACzC,KAAK,OAAO,EAAE,QAAQ,WAAW,EAAE,MAAM;AAAA,IACzC,SAAS,MAAM,QAAQ,EAAE,OAAO,IAAK,EAAE,UAAuB;AAAA,IAC9D,UAAU,OAAO,EAAE,aAAa,WAAW,EAAE,WAAW;AAAA,IACxD,GAAG,OAAO,EAAE,MAAM,WAAW,EAAE,IAAI;AAAA,IACnC,GAAG,OAAO,EAAE,MAAM,WAAW,EAAE,IAAI;AAAA,IACnC,WAAW;AAAA,EACb;AACF;AAEO,SAAS,QAAQ,QAAoB,KAA0B;AACpE,QAAM,QAAQ,OAAO,KAAK,KAAK,OAAK,EAAE,QAAQ,GAAG;AACjD,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR,6BAA6B,GAAG,8BAA8B,OAAO,KAAK,IAAI,OAAK,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,IACtG;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,IAAI,GAAY,OAAuB;AAC9C,MAAI,OAAO,MAAM,SAAU,OAAM,IAAI,MAAM,GAAG,KAAK,iBAAiB;AACpE,SAAO;AACT;AAEA,SAAS,IAAI,GAAY,OAAuB;AAC9C,MAAI,OAAO,MAAM,SAAU,OAAM,IAAI,MAAM,GAAG,KAAK,iBAAiB;AACpE,SAAO;AACT;AAEA,SAAS,KAAK,GAAY,OAAwB;AAChD,MAAI,OAAO,MAAM,UAAW,OAAM,IAAI,MAAM,GAAG,KAAK,kBAAkB;AACtE,SAAO;AACT;AAEA,SAAS,SAAS,GAAY,OAAyB;AACrD,MAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,UAAQ,OAAO,SAAS,QAAQ,GAAG;AACjE,UAAM,IAAI,MAAM,GAAG,KAAK,mBAAmB;AAAA,EAC7C;AACA,SAAO;AACT;","names":[]}
@@ -42,12 +42,16 @@ function loadRequestSigningVectors(options = {}) {
42
42
  negative: loadDir(join(profile32Dir, "negative"), parseNegative, "profile-3.2/negative/")
43
43
  }
44
44
  } : {},
45
- keys: loadKeys(join(sourceDir, "keys.json")),
45
+ keys: loadRequestSigningKeys(options),
46
46
  sourceDir
47
47
  };
48
48
  VECTOR_CACHE.set(sourceDir, loaded);
49
49
  return loaded;
50
50
  }
51
+ function loadRequestSigningKeys(options = {}) {
52
+ const cacheDir = getComplianceCacheDir(options);
53
+ return loadKeys(join(cacheDir, "test-vectors", "request-signing", "keys.json"));
54
+ }
51
55
  function __resetVectorCache() {
52
56
  VECTOR_CACHE.clear();
53
57
  }
@@ -242,6 +246,7 @@ function strArray(v, where) {
242
246
  export {
243
247
  __resetVectorCache,
244
248
  findKey,
249
+ loadRequestSigningKeys,
245
250
  loadRequestSigningVectors
246
251
  };
247
252
  //# sourceMappingURL=vector-loader.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/vector-loader.ts"],"sourcesContent":["import { existsSync, readFileSync, readdirSync } from 'fs';\nimport { basename, join } from 'path';\nimport { getComplianceCacheDir } from '../compliance';\nimport type { RequestSignatureErrorCode } from '../../../signing';\nimport { CONTRACT_IDS } from './types';\nimport type { ContractId, NegativeVector, PositiveVector, TestKeypair, TestKeyset, Vector } from './types';\n\nexport interface LoadVectorsOptions {\n complianceDir?: string;\n version?: string;\n}\n\nexport interface LoadedVectors {\n positive: PositiveVector[];\n negative: NegativeVector[];\n profiles: Record<string, { positive: PositiveVector[]; negative: NegativeVector[] }>;\n keys: TestKeyset;\n sourceDir: string;\n}\n\nconst ERROR_CODES: ReadonlySet<string> = new Set([\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_target_uri_malformed',\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]);\n\nconst CONTRACT_ID_SET: ReadonlySet<string> = new Set(CONTRACT_IDS);\n\n// Memoized per sourceDir — loading 28 JSON fixtures + keys.json on every\n// per-vector call in the runner path added up (~28 disk reads × 2-3 storyboard\n// resolve calls per CLI run). Invariant: the compliance cache is immutable\n// during a process lifetime — `npm run sync-schemas` runs before the process,\n// never concurrently. Cache key is the absolute cacheDir so env-var overrides\n// don't poison the entry.\nconst VECTOR_CACHE = new Map<string, LoadedVectors>();\n\nexport function loadRequestSigningVectors(options: LoadVectorsOptions = {}): LoadedVectors {\n const cacheDir = getComplianceCacheDir(options);\n const sourceDir = join(cacheDir, 'test-vectors', 'request-signing');\n const cached = VECTOR_CACHE.get(sourceDir);\n if (cached) return cached;\n\n if (!existsSync(sourceDir)) {\n throw new Error(\n `Request-signing vectors not found at ${sourceDir}. Run \\`npm run sync-schemas\\` or check your ADCP_COMPLIANCE_DIR.`\n );\n }\n\n const profile32Dir = join(sourceDir, 'profile-3.2');\n const loaded: LoadedVectors = {\n positive: loadDir(join(sourceDir, 'positive'), parsePositive),\n negative: loadDir(join(sourceDir, 'negative'), parseNegative),\n profiles: existsSync(profile32Dir)\n ? {\n '3.2': {\n positive: loadDir(join(profile32Dir, 'positive'), parsePositive, 'profile-3.2/positive/'),\n negative: loadDir(join(profile32Dir, 'negative'), parseNegative, 'profile-3.2/negative/'),\n },\n }\n : {},\n keys: loadKeys(join(sourceDir, 'keys.json')),\n sourceDir,\n };\n VECTOR_CACHE.set(sourceDir, loaded);\n return loaded;\n}\n\n/** Test-only: clear the memoization cache so a fresh cache path is reread. */\nexport function __resetVectorCache(): void {\n VECTOR_CACHE.clear();\n}\n\nfunction loadDir<T extends Vector>(dir: string, parse: (id: string, raw: unknown) => T, idPrefix = ''): T[] {\n if (!existsSync(dir)) {\n throw new Error(`Vector directory missing: ${dir}`);\n }\n const files = readdirSync(dir)\n .filter(f => f.endsWith('.json'))\n .sort();\n return files.map(f => {\n const raw = JSON.parse(readFileSync(join(dir, f), 'utf-8'));\n return parse(`${idPrefix}${vectorIdFromFilename(f)}`, raw);\n });\n}\n\nfunction vectorIdFromFilename(file: string): string {\n return basename(file, '.json');\n}\n\nfunction parsePositive(id: string, raw: unknown): PositiveVector {\n const r = raw as Record<string, unknown>;\n assertSuccess(id, r, true);\n const { jwks_ref, jwks_override } = parseJwksSelector(id, r);\n return {\n kind: 'positive',\n id,\n name: str(r.name, `${id}.name`),\n signing_profile_version: optionalSigningProfileVersion(r),\n reference_now: num(r.reference_now, `${id}.reference_now`),\n request: parseRequest(id, r.request),\n verifier_capability: parseCapability(id, r.verifier_capability),\n jwks_ref,\n jwks_override,\n expected_signature_base: typeof r.expected_signature_base === 'string' ? r.expected_signature_base : undefined,\n spec_reference: typeof r.spec_reference === 'string' ? r.spec_reference : undefined,\n };\n}\n\nfunction parseNegative(id: string, raw: unknown): NegativeVector {\n const r = raw as Record<string, unknown>;\n assertSuccess(id, r, false);\n const outcome = r.expected_outcome as Record<string, unknown>;\n const errorCode = str(outcome.error_code, `${id}.expected_outcome.error_code`);\n if (!ERROR_CODES.has(errorCode)) {\n throw new Error(`${id}: unknown expected_outcome.error_code \"${errorCode}\" (spec drift?)`);\n }\n const failedStep = outcome.failed_step;\n if (typeof failedStep !== 'number' && typeof failedStep !== 'string') {\n throw new Error(`${id}: expected_outcome.failed_step must be number or string`);\n }\n let contract: ContractId | undefined;\n if (r.requires_contract !== undefined) {\n const c = str(r.requires_contract, `${id}.requires_contract`);\n if (!CONTRACT_ID_SET.has(c)) {\n throw new Error(`${id}: unknown requires_contract \"${c}\" (spec drift?)`);\n }\n contract = c as ContractId;\n }\n const { jwks_ref, jwks_override } = parseJwksSelector(id, r);\n return {\n kind: 'negative',\n id,\n name: str(r.name, `${id}.name`),\n signing_profile_version: optionalSigningProfileVersion(r),\n reference_now: num(r.reference_now, `${id}.reference_now`),\n request: parseRequest(id, r.request),\n verifier_capability: parseCapability(id, r.verifier_capability),\n jwks_ref,\n jwks_override,\n expected_error_code: errorCode as RequestSignatureErrorCode,\n expected_failed_step: failedStep,\n requires_contract: contract,\n spec_reference: typeof r.spec_reference === 'string' ? r.spec_reference : undefined,\n };\n}\n\nfunction optionalSigningProfileVersion(vector: Record<string, unknown>): string {\n // Older cached bundles predate the explicit marker; every root vector in\n // those bundles exercises the legacy 3.1 binary profile.\n return typeof vector.signing_profile_version === 'string' ? vector.signing_profile_version : '3.1';\n}\n\nfunction parseJwksSelector(\n id: string,\n r: Record<string, unknown>\n): { jwks_ref?: string[]; jwks_override?: { keys: Array<Record<string, unknown>> } } {\n const hasRef = r.jwks_ref !== undefined;\n const hasOverride = r.jwks_override !== undefined;\n if (hasRef && hasOverride) {\n throw new Error(`${id}: jwks_ref and jwks_override are mutually exclusive`);\n }\n if (!hasRef && !hasOverride) {\n throw new Error(`${id}: must declare either jwks_ref or jwks_override`);\n }\n if (hasOverride) {\n const override = r.jwks_override as Record<string, unknown>;\n const keys = override.keys;\n if (!Array.isArray(keys) || keys.length === 0) {\n throw new Error(`${id}.jwks_override.keys must be a non-empty array`);\n }\n for (const k of keys) {\n if (!k || typeof k !== 'object') {\n throw new Error(`${id}.jwks_override.keys[] entries must be objects`);\n }\n }\n return { jwks_override: { keys: keys as Array<Record<string, unknown>> } };\n }\n return { jwks_ref: strArray(r.jwks_ref, `${id}.jwks_ref`) };\n}\n\nfunction assertSuccess(id: string, vector: Record<string, unknown>, expected: boolean): void {\n const outcome = vector.expected_outcome as Record<string, unknown> | undefined;\n if (!outcome || outcome.success !== expected) {\n throw new Error(\n `${id}: expected_outcome.success must be ${expected} for ${expected ? 'positive' : 'negative'} vector`\n );\n }\n}\n\nfunction parseRequest(id: string, raw: unknown): PositiveVector['request'] {\n const r = raw as Record<string, unknown> | undefined;\n if (!r) throw new Error(`${id}.request missing`);\n const headers = r.headers as Record<string, string> | undefined;\n if (!headers) throw new Error(`${id}.request.headers missing`);\n return {\n method: str(r.method, `${id}.request.method`),\n url: str(r.url, `${id}.request.url`),\n headers: { ...headers },\n body: typeof r.body === 'string' ? r.body : undefined,\n };\n}\n\nfunction parseCapability(id: string, raw: unknown): PositiveVector['verifier_capability'] {\n const r = raw as Record<string, unknown> | undefined;\n if (!r) throw new Error(`${id}.verifier_capability missing`);\n const digest = str(r.covers_content_digest, `${id}.verifier_capability.covers_content_digest`);\n if (digest !== 'required' && digest !== 'forbidden' && digest !== 'either') {\n throw new Error(`${id}: invalid covers_content_digest \"${digest}\"`);\n }\n return {\n supported: bool(r.supported, `${id}.verifier_capability.supported`),\n covers_content_digest: digest,\n required_for: strArray(r.required_for, `${id}.verifier_capability.required_for`),\n supported_for: Array.isArray(r.supported_for) ? (r.supported_for as string[]) : undefined,\n protocol_methods_supported_for: Array.isArray(r.protocol_methods_supported_for)\n ? (r.protocol_methods_supported_for as string[])\n : undefined,\n protocol_methods_required_for: Array.isArray(r.protocol_methods_required_for)\n ? (r.protocol_methods_required_for as string[])\n : undefined,\n };\n}\n\nfunction loadKeys(keysPath: string): TestKeyset {\n if (!existsSync(keysPath)) {\n throw new Error(`keys.json missing at ${keysPath}`);\n }\n const raw = JSON.parse(readFileSync(keysPath, 'utf-8')) as { keys?: unknown };\n if (!Array.isArray(raw.keys)) {\n throw new Error(`keys.json must contain a \"keys\" array`);\n }\n return { keys: raw.keys.map((k, i) => parseKey(i, k)) };\n}\n\nfunction parseKey(index: number, raw: unknown): TestKeypair {\n const r = raw as Record<string, unknown>;\n const where = `keys.json[${index}]`;\n const privateD = r._private_d_for_test_only;\n if (typeof privateD !== 'string' || privateD.length === 0) {\n throw new Error(`${where}._private_d_for_test_only missing (required for dynamic signing)`);\n }\n return {\n kid: str(r.kid, `${where}.kid`),\n kty: str(r.kty, `${where}.kty`),\n crv: typeof r.crv === 'string' ? r.crv : undefined,\n alg: typeof r.alg === 'string' ? r.alg : undefined,\n use: typeof r.use === 'string' ? r.use : undefined,\n key_ops: Array.isArray(r.key_ops) ? (r.key_ops as string[]) : undefined,\n adcp_use: typeof r.adcp_use === 'string' ? r.adcp_use : undefined,\n x: typeof r.x === 'string' ? r.x : undefined,\n y: typeof r.y === 'string' ? r.y : undefined,\n private_d: privateD,\n };\n}\n\nexport function findKey(keyset: TestKeyset, kid: string): TestKeypair {\n const match = keyset.keys.find(k => k.kid === kid);\n if (!match) {\n throw new Error(\n `No test keypair with kid=\"${kid}\" in keys.json (available: ${keyset.keys.map(k => k.kid).join(', ')})`\n );\n }\n return match;\n}\n\nfunction str(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction num(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n\nfunction bool(v: unknown, where: string): boolean {\n if (typeof v !== 'boolean') throw new Error(`${where} must be boolean`);\n return v;\n}\n\nfunction strArray(v: unknown, where: string): string[] {\n if (!Array.isArray(v) || v.some(item => typeof item !== 'string')) {\n throw new Error(`${where} must be string[]`);\n }\n return v as string[];\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/vector-loader.ts"],"sourcesContent":["import { existsSync, readFileSync, readdirSync } from 'fs';\nimport { basename, join } from 'path';\nimport { getComplianceCacheDir } from '../compliance';\nimport type { RequestSignatureErrorCode } from '../../../signing';\nimport { CONTRACT_IDS } from './types';\nimport type { ContractId, NegativeVector, PositiveVector, TestKeypair, TestKeyset, Vector } from './types';\n\nexport interface LoadVectorsOptions {\n complianceDir?: string;\n version?: string;\n}\n\nexport interface LoadedVectors {\n positive: PositiveVector[];\n negative: NegativeVector[];\n profiles: Record<string, { positive: PositiveVector[]; negative: NegativeVector[] }>;\n keys: TestKeyset;\n sourceDir: string;\n}\n\nconst ERROR_CODES: ReadonlySet<string> = new Set([\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_target_uri_malformed',\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]);\n\nconst CONTRACT_ID_SET: ReadonlySet<string> = new Set(CONTRACT_IDS);\n\n// Memoized per sourceDir — loading 28 JSON fixtures + keys.json on every\n// per-vector call in the runner path added up (~28 disk reads × 2-3 storyboard\n// resolve calls per CLI run). Invariant: the compliance cache is immutable\n// during a process lifetime — `npm run sync-schemas` runs before the process,\n// never concurrently. Cache key is the absolute cacheDir so env-var overrides\n// don't poison the entry.\nconst VECTOR_CACHE = new Map<string, LoadedVectors>();\n\nexport function loadRequestSigningVectors(options: LoadVectorsOptions = {}): LoadedVectors {\n const cacheDir = getComplianceCacheDir(options);\n const sourceDir = join(cacheDir, 'test-vectors', 'request-signing');\n const cached = VECTOR_CACHE.get(sourceDir);\n if (cached) return cached;\n\n if (!existsSync(sourceDir)) {\n throw new Error(\n `Request-signing vectors not found at ${sourceDir}. Run \\`npm run sync-schemas\\` or check your ADCP_COMPLIANCE_DIR.`\n );\n }\n\n const profile32Dir = join(sourceDir, 'profile-3.2');\n const loaded: LoadedVectors = {\n positive: loadDir(join(sourceDir, 'positive'), parsePositive),\n negative: loadDir(join(sourceDir, 'negative'), parseNegative),\n profiles: existsSync(profile32Dir)\n ? {\n '3.2': {\n positive: loadDir(join(profile32Dir, 'positive'), parsePositive, 'profile-3.2/positive/'),\n negative: loadDir(join(profile32Dir, 'negative'), parseNegative, 'profile-3.2/negative/'),\n },\n }\n : {},\n keys: loadRequestSigningKeys(options),\n sourceDir,\n };\n VECTOR_CACHE.set(sourceDir, loaded);\n return loaded;\n}\n\n/** Load only the shared signing keyset, without requiring the grader vectors. */\nexport function loadRequestSigningKeys(options: LoadVectorsOptions = {}): TestKeyset {\n const cacheDir = getComplianceCacheDir(options);\n return loadKeys(join(cacheDir, 'test-vectors', 'request-signing', 'keys.json'));\n}\n\n/** Test-only: clear the memoization cache so a fresh cache path is reread. */\nexport function __resetVectorCache(): void {\n VECTOR_CACHE.clear();\n}\n\nfunction loadDir<T extends Vector>(dir: string, parse: (id: string, raw: unknown) => T, idPrefix = ''): T[] {\n if (!existsSync(dir)) {\n throw new Error(`Vector directory missing: ${dir}`);\n }\n const files = readdirSync(dir)\n .filter(f => f.endsWith('.json'))\n .sort();\n return files.map(f => {\n const raw = JSON.parse(readFileSync(join(dir, f), 'utf-8'));\n return parse(`${idPrefix}${vectorIdFromFilename(f)}`, raw);\n });\n}\n\nfunction vectorIdFromFilename(file: string): string {\n return basename(file, '.json');\n}\n\nfunction parsePositive(id: string, raw: unknown): PositiveVector {\n const r = raw as Record<string, unknown>;\n assertSuccess(id, r, true);\n const { jwks_ref, jwks_override } = parseJwksSelector(id, r);\n return {\n kind: 'positive',\n id,\n name: str(r.name, `${id}.name`),\n signing_profile_version: optionalSigningProfileVersion(r),\n reference_now: num(r.reference_now, `${id}.reference_now`),\n request: parseRequest(id, r.request),\n verifier_capability: parseCapability(id, r.verifier_capability),\n jwks_ref,\n jwks_override,\n expected_signature_base: typeof r.expected_signature_base === 'string' ? r.expected_signature_base : undefined,\n spec_reference: typeof r.spec_reference === 'string' ? r.spec_reference : undefined,\n };\n}\n\nfunction parseNegative(id: string, raw: unknown): NegativeVector {\n const r = raw as Record<string, unknown>;\n assertSuccess(id, r, false);\n const outcome = r.expected_outcome as Record<string, unknown>;\n const errorCode = str(outcome.error_code, `${id}.expected_outcome.error_code`);\n if (!ERROR_CODES.has(errorCode)) {\n throw new Error(`${id}: unknown expected_outcome.error_code \"${errorCode}\" (spec drift?)`);\n }\n const failedStep = outcome.failed_step;\n if (typeof failedStep !== 'number' && typeof failedStep !== 'string') {\n throw new Error(`${id}: expected_outcome.failed_step must be number or string`);\n }\n let contract: ContractId | undefined;\n if (r.requires_contract !== undefined) {\n const c = str(r.requires_contract, `${id}.requires_contract`);\n if (!CONTRACT_ID_SET.has(c)) {\n throw new Error(`${id}: unknown requires_contract \"${c}\" (spec drift?)`);\n }\n contract = c as ContractId;\n }\n const { jwks_ref, jwks_override } = parseJwksSelector(id, r);\n return {\n kind: 'negative',\n id,\n name: str(r.name, `${id}.name`),\n signing_profile_version: optionalSigningProfileVersion(r),\n reference_now: num(r.reference_now, `${id}.reference_now`),\n request: parseRequest(id, r.request),\n verifier_capability: parseCapability(id, r.verifier_capability),\n jwks_ref,\n jwks_override,\n expected_error_code: errorCode as RequestSignatureErrorCode,\n expected_failed_step: failedStep,\n requires_contract: contract,\n spec_reference: typeof r.spec_reference === 'string' ? r.spec_reference : undefined,\n };\n}\n\nfunction optionalSigningProfileVersion(vector: Record<string, unknown>): string {\n // Older cached bundles predate the explicit marker; every root vector in\n // those bundles exercises the legacy 3.1 binary profile.\n return typeof vector.signing_profile_version === 'string' ? vector.signing_profile_version : '3.1';\n}\n\nfunction parseJwksSelector(\n id: string,\n r: Record<string, unknown>\n): { jwks_ref?: string[]; jwks_override?: { keys: Array<Record<string, unknown>> } } {\n const hasRef = r.jwks_ref !== undefined;\n const hasOverride = r.jwks_override !== undefined;\n if (hasRef && hasOverride) {\n throw new Error(`${id}: jwks_ref and jwks_override are mutually exclusive`);\n }\n if (!hasRef && !hasOverride) {\n throw new Error(`${id}: must declare either jwks_ref or jwks_override`);\n }\n if (hasOverride) {\n const override = r.jwks_override as Record<string, unknown>;\n const keys = override.keys;\n if (!Array.isArray(keys) || keys.length === 0) {\n throw new Error(`${id}.jwks_override.keys must be a non-empty array`);\n }\n for (const k of keys) {\n if (!k || typeof k !== 'object') {\n throw new Error(`${id}.jwks_override.keys[] entries must be objects`);\n }\n }\n return { jwks_override: { keys: keys as Array<Record<string, unknown>> } };\n }\n return { jwks_ref: strArray(r.jwks_ref, `${id}.jwks_ref`) };\n}\n\nfunction assertSuccess(id: string, vector: Record<string, unknown>, expected: boolean): void {\n const outcome = vector.expected_outcome as Record<string, unknown> | undefined;\n if (!outcome || outcome.success !== expected) {\n throw new Error(\n `${id}: expected_outcome.success must be ${expected} for ${expected ? 'positive' : 'negative'} vector`\n );\n }\n}\n\nfunction parseRequest(id: string, raw: unknown): PositiveVector['request'] {\n const r = raw as Record<string, unknown> | undefined;\n if (!r) throw new Error(`${id}.request missing`);\n const headers = r.headers as Record<string, string> | undefined;\n if (!headers) throw new Error(`${id}.request.headers missing`);\n return {\n method: str(r.method, `${id}.request.method`),\n url: str(r.url, `${id}.request.url`),\n headers: { ...headers },\n body: typeof r.body === 'string' ? r.body : undefined,\n };\n}\n\nfunction parseCapability(id: string, raw: unknown): PositiveVector['verifier_capability'] {\n const r = raw as Record<string, unknown> | undefined;\n if (!r) throw new Error(`${id}.verifier_capability missing`);\n const digest = str(r.covers_content_digest, `${id}.verifier_capability.covers_content_digest`);\n if (digest !== 'required' && digest !== 'forbidden' && digest !== 'either') {\n throw new Error(`${id}: invalid covers_content_digest \"${digest}\"`);\n }\n return {\n supported: bool(r.supported, `${id}.verifier_capability.supported`),\n covers_content_digest: digest,\n required_for: strArray(r.required_for, `${id}.verifier_capability.required_for`),\n supported_for: Array.isArray(r.supported_for) ? (r.supported_for as string[]) : undefined,\n protocol_methods_supported_for: Array.isArray(r.protocol_methods_supported_for)\n ? (r.protocol_methods_supported_for as string[])\n : undefined,\n protocol_methods_required_for: Array.isArray(r.protocol_methods_required_for)\n ? (r.protocol_methods_required_for as string[])\n : undefined,\n };\n}\n\nfunction loadKeys(keysPath: string): TestKeyset {\n if (!existsSync(keysPath)) {\n throw new Error(`keys.json missing at ${keysPath}`);\n }\n const raw = JSON.parse(readFileSync(keysPath, 'utf-8')) as { keys?: unknown };\n if (!Array.isArray(raw.keys)) {\n throw new Error(`keys.json must contain a \"keys\" array`);\n }\n return { keys: raw.keys.map((k, i) => parseKey(i, k)) };\n}\n\nfunction parseKey(index: number, raw: unknown): TestKeypair {\n const r = raw as Record<string, unknown>;\n const where = `keys.json[${index}]`;\n const privateD = r._private_d_for_test_only;\n if (typeof privateD !== 'string' || privateD.length === 0) {\n throw new Error(`${where}._private_d_for_test_only missing (required for dynamic signing)`);\n }\n return {\n kid: str(r.kid, `${where}.kid`),\n kty: str(r.kty, `${where}.kty`),\n crv: typeof r.crv === 'string' ? r.crv : undefined,\n alg: typeof r.alg === 'string' ? r.alg : undefined,\n use: typeof r.use === 'string' ? r.use : undefined,\n key_ops: Array.isArray(r.key_ops) ? (r.key_ops as string[]) : undefined,\n adcp_use: typeof r.adcp_use === 'string' ? r.adcp_use : undefined,\n x: typeof r.x === 'string' ? r.x : undefined,\n y: typeof r.y === 'string' ? r.y : undefined,\n private_d: privateD,\n };\n}\n\nexport function findKey(keyset: TestKeyset, kid: string): TestKeypair {\n const match = keyset.keys.find(k => k.kid === kid);\n if (!match) {\n throw new Error(\n `No test keypair with kid=\"${kid}\" in keys.json (available: ${keyset.keys.map(k => k.kid).join(', ')})`\n );\n }\n return match;\n}\n\nfunction str(v: unknown, where: string): string {\n if (typeof v !== 'string') throw new Error(`${where} must be string`);\n return v;\n}\n\nfunction num(v: unknown, where: string): number {\n if (typeof v !== 'number') throw new Error(`${where} must be number`);\n return v;\n}\n\nfunction bool(v: unknown, where: string): boolean {\n if (typeof v !== 'boolean') throw new Error(`${where} must be boolean`);\n return v;\n}\n\nfunction strArray(v: unknown, where: string): string[] {\n if (!Array.isArray(v) || v.some(item => typeof item !== 'string')) {\n throw new Error(`${where} must be string[]`);\n }\n return v as string[];\n}\n"],"mappings":"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","names":[]}