@apifuse/provider-sdk 2.2.0-beta.7 → 2.2.0-beta.70

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 (478) hide show
  1. package/AUTHORING.md +943 -51
  2. package/CHANGELOG.md +273 -1
  3. package/LICENSE +21 -0
  4. package/README.md +117 -29
  5. package/SUBMISSION.md +3 -2
  6. package/bin/apifuse-check.ts +293 -13
  7. package/bin/apifuse-dev.ts +42 -19
  8. package/bin/apifuse-migrate-deployment.ts +200 -0
  9. package/bin/apifuse-migrate-operation-declaration.ts +55 -0
  10. package/bin/apifuse-migrate-shape.ts +202 -0
  11. package/bin/apifuse-pack-check.ts +19 -6
  12. package/bin/apifuse-pack-smoke.ts +57 -2
  13. package/bin/apifuse-pack-types.ts +736 -38
  14. package/bin/apifuse-perf.ts +59 -23
  15. package/bin/apifuse-record.ts +923 -94
  16. package/bin/apifuse-submit-check.ts +2313 -281
  17. package/bin/apifuse-test.ts +3 -1
  18. package/bin/submit-check-delimited-text.ts +50 -0
  19. package/dist/auth-turn/index.d.ts +3 -3
  20. package/dist/auth-turn/index.js +1 -1
  21. package/dist/auth.d.ts +14 -0
  22. package/dist/auth.js +67 -0
  23. package/dist/ceremonies/index.d.ts +16 -0
  24. package/dist/ceremonies/index.js +141 -36
  25. package/dist/cli/commands.d.ts +1 -1
  26. package/dist/cli/commands.js +30 -0
  27. package/dist/cli/create.d.ts +1 -1
  28. package/dist/cli/create.js +8 -2
  29. package/dist/cli/deployment-intent.d.ts +178 -0
  30. package/dist/cli/deployment-intent.js +277 -0
  31. package/dist/cli/local-connection.d.ts +111 -0
  32. package/dist/cli/local-connection.js +151 -0
  33. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  34. package/dist/cli/migrate-deployment-intent.js +1552 -0
  35. package/dist/cli/migrate-operation-declaration.d.ts +70 -0
  36. package/dist/cli/migrate-operation-declaration.js +2206 -0
  37. package/dist/cli/migrate-operation-shape.d.ts +44 -0
  38. package/dist/cli/migrate-operation-shape.js +113 -0
  39. package/dist/cli/migrate-provider-shape.d.ts +56 -0
  40. package/dist/cli/migrate-provider-shape.js +580 -0
  41. package/dist/cli/resolver-runtime.d.ts +21 -0
  42. package/dist/cli/resolver-runtime.js +31 -0
  43. package/dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
  44. package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
  45. package/dist/cli/templates/provider/README.md.tpl +41 -19
  46. package/dist/cli/templates/provider/index.ts.tpl +6 -3
  47. package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
  48. package/dist/cli/templates/provider/provider.json.tpl +6 -0
  49. package/dist/config/loader.d.ts +202 -16
  50. package/dist/config/loader.js +491 -141
  51. package/dist/contract-serialization.js +4 -8
  52. package/dist/contract-types.d.ts +12 -5
  53. package/dist/contract.js +24 -10
  54. package/dist/declaration-validation.d.ts +34 -0
  55. package/dist/declaration-validation.js +305 -0
  56. package/dist/define.d.ts +71 -29
  57. package/dist/define.js +807 -69
  58. package/dist/dev.d.ts +5 -0
  59. package/dist/dev.js +8 -1
  60. package/dist/engine.d.ts +129 -0
  61. package/dist/engine.js +209 -0
  62. package/dist/error-observability.d.ts +7 -0
  63. package/dist/error-observability.js +61 -0
  64. package/dist/error-resolution.d.ts +18 -0
  65. package/dist/error-resolution.js +243 -0
  66. package/dist/errors.d.ts +74 -0
  67. package/dist/errors.js +99 -0
  68. package/dist/fixture-sanitization.d.ts +28 -0
  69. package/dist/fixture-sanitization.js +371 -0
  70. package/dist/handle-meta.d.ts +90 -0
  71. package/dist/handle-meta.js +73 -0
  72. package/dist/handle.d.ts +226 -0
  73. package/dist/handle.js +345 -0
  74. package/dist/health-scenario.d.ts +1901 -0
  75. package/dist/health-scenario.js +653 -0
  76. package/dist/i18n/catalog.js +21 -1
  77. package/dist/i18n/error-messages.d.ts +86 -0
  78. package/dist/i18n/error-messages.js +192 -0
  79. package/dist/i18n/index.d.ts +1 -0
  80. package/dist/i18n/index.js +1 -0
  81. package/dist/i18n/keys.d.ts +12 -0
  82. package/dist/i18n/keys.js +76 -5
  83. package/dist/i18n/operation-locale-namespace.d.ts +2 -0
  84. package/dist/i18n/operation-locale-namespace.js +7 -0
  85. package/dist/index.d.ts +40 -15
  86. package/dist/index.js +29 -11
  87. package/dist/lint.d.ts +43 -11
  88. package/dist/lint.js +2512 -177
  89. package/dist/native-address.d.ts +43 -0
  90. package/dist/native-address.js +281 -0
  91. package/dist/native-egress-policy.d.ts +31 -0
  92. package/dist/native-egress-policy.js +288 -0
  93. package/dist/observability.d.ts +5 -2
  94. package/dist/observability.js +48 -1
  95. package/dist/provider.d.ts +18 -8
  96. package/dist/provider.js +11 -6
  97. package/dist/runtime/auth-flow.d.ts +6 -1
  98. package/dist/runtime/auth-flow.js +8 -0
  99. package/dist/runtime/bounded-expiring-map.d.ts +21 -0
  100. package/dist/runtime/bounded-expiring-map.js +64 -0
  101. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  102. package/dist/runtime/browser-telemetry-binding.js +83 -0
  103. package/dist/runtime/browser-telemetry.d.ts +76 -0
  104. package/dist/runtime/browser-telemetry.js +165 -0
  105. package/dist/runtime/browser.d.ts +4 -0
  106. package/dist/runtime/browser.js +688 -83
  107. package/dist/runtime/cache-telemetry.d.ts +71 -0
  108. package/dist/runtime/cache-telemetry.js +177 -0
  109. package/dist/runtime/cache.d.ts +3 -0
  110. package/dist/runtime/cache.js +245 -23
  111. package/dist/runtime/capability-response.d.ts +3 -0
  112. package/dist/runtime/capability-response.js +56 -0
  113. package/dist/runtime/capability-telemetry.d.ts +46 -0
  114. package/dist/runtime/capability-telemetry.js +68 -0
  115. package/dist/runtime/chrome149-header-order.d.ts +58 -0
  116. package/dist/runtime/chrome149-header-order.js +289 -0
  117. package/dist/runtime/diagnostic-env-values.d.ts +5 -0
  118. package/dist/runtime/diagnostic-env-values.js +57 -0
  119. package/dist/runtime/diagnostic-env.d.ts +14 -0
  120. package/dist/runtime/diagnostic-env.js +44 -0
  121. package/dist/runtime/diagnostic-redactor.d.ts +54 -0
  122. package/dist/runtime/diagnostic-redactor.js +571 -0
  123. package/dist/runtime/egress-lease.d.ts +65 -0
  124. package/dist/runtime/egress-lease.js +236 -0
  125. package/dist/runtime/engine-mode.d.ts +74 -0
  126. package/dist/runtime/engine-mode.js +152 -0
  127. package/dist/runtime/env.js +14 -1
  128. package/dist/runtime/executor.d.ts +3 -2
  129. package/dist/runtime/executor.js +23 -26
  130. package/dist/runtime/handle-wordlist.d.ts +43 -0
  131. package/dist/runtime/handle-wordlist.js +256 -0
  132. package/dist/runtime/handle.d.ts +71 -0
  133. package/dist/runtime/handle.js +908 -0
  134. package/dist/runtime/http-telemetry-binding.d.ts +10 -0
  135. package/dist/runtime/http-telemetry-binding.js +152 -0
  136. package/dist/runtime/http-telemetry-guard.d.ts +16 -0
  137. package/dist/runtime/http-telemetry-guard.js +202 -0
  138. package/dist/runtime/http-telemetry.d.ts +104 -0
  139. package/dist/runtime/http-telemetry.js +190 -0
  140. package/dist/runtime/http.d.ts +34 -0
  141. package/dist/runtime/http.js +680 -121
  142. package/dist/runtime/insights.js +2 -2
  143. package/dist/runtime/instrumentation.d.ts +2 -2
  144. package/dist/runtime/instrumentation.js +462 -19
  145. package/dist/runtime/native-network-errors.d.ts +33 -0
  146. package/dist/runtime/native-network-errors.js +69 -0
  147. package/dist/runtime/native-network.d.ts +105 -0
  148. package/dist/runtime/native-network.js +1433 -0
  149. package/dist/runtime/native-telemetry.d.ts +142 -0
  150. package/dist/runtime/native-telemetry.js +231 -0
  151. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  152. package/dist/runtime/ocr-telemetry.js +192 -0
  153. package/dist/runtime/ocr.d.ts +29 -0
  154. package/dist/runtime/ocr.js +468 -0
  155. package/dist/runtime/otlp.d.ts +71 -2
  156. package/dist/runtime/otlp.js +398 -16
  157. package/dist/runtime/provider.d.ts +7 -0
  158. package/dist/runtime/provider.js +14 -0
  159. package/dist/runtime/proxy-errors.js +6 -2
  160. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  161. package/dist/runtime/proxy-nodemaven.js +147 -0
  162. package/dist/runtime/proxy-retry-policy.d.ts +4 -1
  163. package/dist/runtime/proxy-retry-policy.js +11 -2
  164. package/dist/runtime/proxy-telemetry.d.ts +133 -3
  165. package/dist/runtime/proxy-telemetry.js +218 -70
  166. package/dist/runtime/redirect-hop-headers.d.ts +19 -0
  167. package/dist/runtime/redirect-hop-headers.js +58 -0
  168. package/dist/runtime/redirects.d.ts +61 -0
  169. package/dist/runtime/redirects.js +149 -0
  170. package/dist/runtime/redis.d.ts +1 -1
  171. package/dist/runtime/redis.js +4 -2
  172. package/dist/runtime/request-options.d.ts +75 -1
  173. package/dist/runtime/request-options.js +588 -0
  174. package/dist/runtime/request-telemetry.d.ts +70 -0
  175. package/dist/runtime/request-telemetry.js +229 -0
  176. package/dist/runtime/resolver-config.d.ts +13 -0
  177. package/dist/runtime/resolver-config.js +14 -0
  178. package/dist/runtime/resolver-public.d.ts +3 -0
  179. package/dist/runtime/resolver-public.js +1 -0
  180. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  181. package/dist/runtime/resolver-runtime-options.js +33 -0
  182. package/dist/runtime/resolver-shared.d.ts +24 -0
  183. package/dist/runtime/resolver-shared.js +69 -0
  184. package/dist/runtime/resolver-span-attributes.d.ts +34 -0
  185. package/dist/runtime/resolver-span-attributes.js +93 -0
  186. package/dist/runtime/resolver-telemetry.d.ts +135 -0
  187. package/dist/runtime/resolver-telemetry.js +204 -0
  188. package/dist/runtime/resolver-usage.d.ts +32 -0
  189. package/dist/runtime/resolver-usage.js +54 -0
  190. package/dist/runtime/resolver-vendors/bindings.d.ts +53 -0
  191. package/dist/runtime/resolver-vendors/bindings.js +45 -0
  192. package/dist/runtime/resolver-vendors/browser.d.ts +24 -0
  193. package/dist/runtime/resolver-vendors/browser.js +423 -0
  194. package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
  195. package/dist/runtime/resolver-vendors/capsolver.js +544 -0
  196. package/dist/runtime/resolver-vendors/hosts.d.ts +23 -0
  197. package/dist/runtime/resolver-vendors/hosts.js +68 -0
  198. package/dist/runtime/resolver-vendors/hypersolutions.d.ts +27 -0
  199. package/dist/runtime/resolver-vendors/hypersolutions.js +369 -0
  200. package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
  201. package/dist/runtime/resolver-vendors/twocaptcha.js +425 -0
  202. package/dist/runtime/resolver-vendors/types.d.ts +125 -0
  203. package/dist/runtime/resolver-vendors/types.js +106 -0
  204. package/dist/runtime/resolver.d.ts +79 -0
  205. package/dist/runtime/resolver.js +1094 -0
  206. package/dist/runtime/state-telemetry.d.ts +79 -0
  207. package/dist/runtime/state-telemetry.js +194 -0
  208. package/dist/runtime/state.d.ts +10 -1
  209. package/dist/runtime/state.js +322 -82
  210. package/dist/runtime/stealth-akamai-sbsd.d.ts +54 -0
  211. package/dist/runtime/stealth-akamai-sbsd.js +142 -0
  212. package/dist/runtime/stealth-cookies.d.ts +24 -0
  213. package/dist/runtime/stealth-cookies.js +131 -0
  214. package/dist/runtime/stealth-owned-headers.d.ts +39 -0
  215. package/dist/runtime/stealth-owned-headers.js +57 -0
  216. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  217. package/dist/runtime/stealth-telemetry.js +179 -0
  218. package/dist/runtime/stealth.d.ts +45 -6
  219. package/dist/runtime/stealth.js +1775 -320
  220. package/dist/runtime/stt-telemetry.d.ts +77 -0
  221. package/dist/runtime/stt-telemetry.js +176 -0
  222. package/dist/runtime/stt.js +18 -19
  223. package/dist/runtime/timeout.d.ts +5 -0
  224. package/dist/runtime/timeout.js +12 -0
  225. package/dist/runtime/trace-config.d.ts +12 -0
  226. package/dist/runtime/trace-config.js +62 -0
  227. package/dist/runtime/trace.d.ts +17 -0
  228. package/dist/runtime/trace.js +176 -25
  229. package/dist/runtime-boundary-lint.d.ts +137 -0
  230. package/dist/runtime-boundary-lint.js +590 -0
  231. package/dist/schema.d.ts +20 -0
  232. package/dist/schema.js +72 -2
  233. package/dist/serve.d.ts +1 -1
  234. package/dist/serve.js +1 -1
  235. package/dist/server/error-observability.d.ts +1 -0
  236. package/dist/server/error-observability.js +1 -0
  237. package/dist/server/error-stack-frames.d.ts +35 -0
  238. package/dist/server/error-stack-frames.js +219 -0
  239. package/dist/server/index.d.ts +21 -2
  240. package/dist/server/index.js +11 -2
  241. package/dist/server/runtime-diagnostics.d.ts +165 -0
  242. package/dist/server/runtime-diagnostics.js +360 -0
  243. package/dist/server/sdk-version.d.ts +3 -0
  244. package/dist/server/sdk-version.js +19 -0
  245. package/dist/server/self-test-input-tokens.d.ts +2 -1
  246. package/dist/server/self-test-input-tokens.js +18 -14
  247. package/dist/server/self-test-redaction.js +8 -33
  248. package/dist/server/self-test.d.ts +18 -3
  249. package/dist/server/self-test.js +139 -76
  250. package/dist/server/sensitive-values.d.ts +26 -0
  251. package/dist/server/sensitive-values.js +137 -0
  252. package/dist/server/serve-implementation.d.ts +285 -0
  253. package/dist/server/serve-implementation.js +3172 -0
  254. package/dist/server/serve.d.ts +1 -75
  255. package/dist/server/serve.js +1 -1170
  256. package/dist/server/state-backend-report.d.ts +70 -0
  257. package/dist/server/state-backend-report.js +113 -0
  258. package/dist/server/trace-output.d.ts +7 -0
  259. package/dist/server/trace-output.js +111 -0
  260. package/dist/server/types.d.ts +37 -5
  261. package/dist/server/types.js +34 -1
  262. package/dist/stateful/errors.d.ts +19 -0
  263. package/dist/stateful/errors.js +24 -0
  264. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  265. package/dist/stateful/http-provider-event-emitter.js +237 -0
  266. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  267. package/dist/stateful/http-session-owner-registry.js +210 -0
  268. package/dist/stateful/index.d.ts +18 -0
  269. package/dist/stateful/index.js +18 -0
  270. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  271. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  272. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  273. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  274. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  275. package/dist/stateful/provider-event-pipeline.js +1 -0
  276. package/dist/stateful/provider-events.d.ts +101 -0
  277. package/dist/stateful/provider-events.js +289 -0
  278. package/dist/stateful/session-key.d.ts +15 -0
  279. package/dist/stateful/session-key.js +86 -0
  280. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  281. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  282. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  283. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  284. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  285. package/dist/stateful/stateful-provider-adapter.js +287 -0
  286. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  287. package/dist/stateful/stateful-provider-observability.js +161 -0
  288. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  289. package/dist/stateful/stateful-provider-owner-forwarder.js +237 -0
  290. package/dist/stateful/stateful-provider-runtime-context.d.ts +35 -0
  291. package/dist/stateful/stateful-provider-runtime-context.js +61 -0
  292. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  293. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  294. package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
  295. package/dist/stateful/stateful-provider-session-routing.js +345 -0
  296. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  297. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  298. package/dist/stateful-signing.d.ts +18 -0
  299. package/dist/stateful-signing.js +27 -0
  300. package/dist/stealth/profiles.d.ts +15 -4
  301. package/dist/stealth/profiles.js +169 -211
  302. package/dist/stream-evidence.d.ts +74 -0
  303. package/dist/stream-evidence.js +785 -0
  304. package/dist/stream.js +7 -1
  305. package/dist/testing/index.d.ts +2 -1
  306. package/dist/testing/index.js +2 -1
  307. package/dist/testing/run.d.ts +32 -2
  308. package/dist/testing/run.js +509 -25
  309. package/dist/trace-sanitization.d.ts +6 -0
  310. package/dist/trace-sanitization.js +68 -0
  311. package/dist/types.d.ts +899 -210
  312. package/dist/types.js +1 -0
  313. package/dist/typescript-module.d.ts +39 -0
  314. package/dist/typescript-module.js +72 -0
  315. package/package.json +52 -6
  316. package/src/auth-turn/index.ts +1 -1
  317. package/src/auth.ts +118 -0
  318. package/src/ceremonies/index.ts +189 -46
  319. package/src/cli/commands.ts +37 -0
  320. package/src/cli/create.ts +8 -2
  321. package/src/cli/deployment-intent.ts +364 -0
  322. package/src/cli/local-connection.ts +221 -0
  323. package/src/cli/migrate-deployment-intent.ts +1908 -0
  324. package/src/cli/migrate-operation-declaration.ts +3026 -0
  325. package/src/cli/migrate-operation-shape.ts +184 -0
  326. package/src/cli/migrate-provider-shape.ts +778 -0
  327. package/src/cli/resolver-runtime.ts +72 -0
  328. package/src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
  329. package/src/cli/templates/provider/Dockerfile.tpl +1 -1
  330. package/src/cli/templates/provider/README.md.tpl +41 -19
  331. package/src/cli/templates/provider/index.ts.tpl +6 -3
  332. package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
  333. package/src/cli/templates/provider/provider.json.tpl +6 -0
  334. package/src/config/loader.ts +774 -181
  335. package/src/contract-serialization.ts +5 -7
  336. package/src/contract-types.ts +12 -5
  337. package/src/contract.ts +24 -10
  338. package/src/declaration-validation.ts +376 -0
  339. package/src/define.ts +1105 -131
  340. package/src/dev.ts +13 -1
  341. package/src/engine.ts +390 -0
  342. package/src/error-observability.ts +64 -0
  343. package/src/error-resolution.ts +269 -0
  344. package/src/errors.ts +157 -0
  345. package/src/fixture-sanitization.ts +422 -0
  346. package/src/handle-meta.ts +143 -0
  347. package/src/handle.ts +694 -0
  348. package/src/health-scenario.ts +960 -0
  349. package/src/i18n/catalog.ts +23 -1
  350. package/src/i18n/error-messages.ts +255 -0
  351. package/src/i18n/index.ts +1 -0
  352. package/src/i18n/keys.ts +80 -6
  353. package/src/i18n/operation-locale-namespace.ts +10 -0
  354. package/src/index.ts +390 -23
  355. package/src/lint.ts +2975 -234
  356. package/src/native-address.ts +340 -0
  357. package/src/native-egress-policy.ts +358 -0
  358. package/src/observability.ts +51 -1
  359. package/src/provider.ts +207 -27
  360. package/src/runtime/auth-flow.ts +15 -0
  361. package/src/runtime/bounded-expiring-map.ts +67 -0
  362. package/src/runtime/browser-telemetry-binding.ts +92 -0
  363. package/src/runtime/browser-telemetry.ts +289 -0
  364. package/src/runtime/browser.ts +882 -99
  365. package/src/runtime/cache-telemetry.ts +247 -0
  366. package/src/runtime/cache.ts +258 -22
  367. package/src/runtime/capability-response.ts +53 -0
  368. package/src/runtime/capability-telemetry.ts +101 -0
  369. package/src/runtime/chrome149-header-order.ts +330 -0
  370. package/src/runtime/diagnostic-env-values.ts +56 -0
  371. package/src/runtime/diagnostic-env.ts +65 -0
  372. package/src/runtime/diagnostic-redactor.ts +668 -0
  373. package/src/runtime/egress-lease.ts +341 -0
  374. package/src/runtime/engine-mode.ts +233 -0
  375. package/src/runtime/env.ts +15 -1
  376. package/src/runtime/executor.ts +39 -32
  377. package/src/runtime/handle-wordlist.ts +266 -0
  378. package/src/runtime/handle.ts +1180 -0
  379. package/src/runtime/http-telemetry-binding.ts +162 -0
  380. package/src/runtime/http-telemetry-guard.ts +208 -0
  381. package/src/runtime/http-telemetry.ts +292 -0
  382. package/src/runtime/http.ts +896 -150
  383. package/src/runtime/insights.ts +2 -2
  384. package/src/runtime/instrumentation.ts +628 -28
  385. package/src/runtime/native-network-errors.ts +99 -0
  386. package/src/runtime/native-network.ts +1853 -0
  387. package/src/runtime/native-telemetry.ts +366 -0
  388. package/src/runtime/ocr-telemetry.ts +308 -0
  389. package/src/runtime/ocr.ts +564 -0
  390. package/src/runtime/otlp.ts +468 -21
  391. package/src/runtime/provider.ts +15 -0
  392. package/src/runtime/proxy-errors.ts +12 -4
  393. package/src/runtime/proxy-nodemaven.ts +222 -0
  394. package/src/runtime/proxy-retry-policy.ts +12 -1
  395. package/src/runtime/proxy-telemetry.ts +358 -103
  396. package/src/runtime/redirect-hop-headers.ts +71 -0
  397. package/src/runtime/redirects.ts +215 -0
  398. package/src/runtime/redis.ts +7 -2
  399. package/src/runtime/request-options.ts +728 -1
  400. package/src/runtime/request-telemetry.ts +375 -0
  401. package/src/runtime/resolver-config.ts +18 -0
  402. package/src/runtime/resolver-public.ts +44 -0
  403. package/src/runtime/resolver-runtime-options.ts +50 -0
  404. package/src/runtime/resolver-shared.ts +113 -0
  405. package/src/runtime/resolver-span-attributes.ts +139 -0
  406. package/src/runtime/resolver-telemetry.ts +362 -0
  407. package/src/runtime/resolver-usage.ts +99 -0
  408. package/src/runtime/resolver-vendors/bindings.ts +61 -0
  409. package/src/runtime/resolver-vendors/browser.ts +591 -0
  410. package/src/runtime/resolver-vendors/capsolver.ts +727 -0
  411. package/src/runtime/resolver-vendors/hosts.ts +81 -0
  412. package/src/runtime/resolver-vendors/hypersolutions.ts +480 -0
  413. package/src/runtime/resolver-vendors/twocaptcha.ts +555 -0
  414. package/src/runtime/resolver-vendors/types.ts +261 -0
  415. package/src/runtime/resolver.ts +1543 -0
  416. package/src/runtime/state-telemetry.ts +298 -0
  417. package/src/runtime/state.ts +435 -89
  418. package/src/runtime/stealth-akamai-sbsd.ts +207 -0
  419. package/src/runtime/stealth-cookies.ts +155 -0
  420. package/src/runtime/stealth-owned-headers.ts +67 -0
  421. package/src/runtime/stealth-telemetry.ts +309 -0
  422. package/src/runtime/stealth.ts +2275 -372
  423. package/src/runtime/stt-telemetry.ts +282 -0
  424. package/src/runtime/stt.ts +96 -91
  425. package/src/runtime/timeout.ts +18 -0
  426. package/src/runtime/trace-config.ts +78 -0
  427. package/src/runtime/trace.ts +257 -35
  428. package/src/runtime-boundary-lint.ts +707 -0
  429. package/src/schema.ts +80 -2
  430. package/src/serve.ts +6 -1
  431. package/src/server/error-observability.ts +1 -0
  432. package/src/server/error-stack-frames.ts +214 -0
  433. package/src/server/index.ts +184 -2
  434. package/src/server/runtime-diagnostics.ts +522 -0
  435. package/src/server/sdk-version.ts +22 -0
  436. package/src/server/self-test-input-tokens.ts +29 -14
  437. package/src/server/self-test-redaction.ts +10 -40
  438. package/src/server/self-test.ts +205 -89
  439. package/src/server/sensitive-values.ts +211 -0
  440. package/src/server/serve-implementation.ts +4596 -0
  441. package/src/server/serve.ts +1 -1685
  442. package/src/server/state-backend-report.ts +185 -0
  443. package/src/server/trace-output.ts +189 -0
  444. package/src/server/types.ts +34 -1
  445. package/src/stateful/README.md +146 -0
  446. package/src/stateful/errors.ts +35 -0
  447. package/src/stateful/http-provider-event-emitter.ts +314 -0
  448. package/src/stateful/http-session-owner-registry.ts +306 -0
  449. package/src/stateful/index.ts +18 -0
  450. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  451. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  452. package/src/stateful/provider-event-pipeline.ts +61 -0
  453. package/src/stateful/provider-events.ts +462 -0
  454. package/src/stateful/session-key.ts +111 -0
  455. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  456. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  457. package/src/stateful/stateful-provider-adapter.ts +562 -0
  458. package/src/stateful/stateful-provider-observability.ts +261 -0
  459. package/src/stateful/stateful-provider-owner-forwarder.ts +310 -0
  460. package/src/stateful/stateful-provider-runtime-context.ts +96 -0
  461. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  462. package/src/stateful/stateful-provider-session-routing.ts +546 -0
  463. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  464. package/src/stateful-signing.ts +46 -0
  465. package/src/stealth/profiles.ts +212 -231
  466. package/src/stream-evidence.ts +988 -0
  467. package/src/stream.ts +8 -1
  468. package/src/testing/index.ts +10 -1
  469. package/src/testing/run.ts +685 -19
  470. package/src/trace-sanitization.ts +110 -0
  471. package/src/types.ts +1014 -273
  472. package/src/typescript-module.ts +100 -0
  473. package/dist/choice-token.d.ts +0 -24
  474. package/dist/choice-token.js +0 -74
  475. package/dist/runtime/choice.d.ts +0 -15
  476. package/dist/runtime/choice.js +0 -413
  477. package/src/choice-token.ts +0 -165
  478. package/src/runtime/choice.ts +0 -686
@@ -0,0 +1,100 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ const requireModule = createRequire(import.meta.url);
4
+
5
+ /** The TypeScript compiler API surface the source-level lint rules parse with. */
6
+ export type TypeScriptModule = typeof import("typescript");
7
+
8
+ /**
9
+ * What a caller hands over as a compiler module. Typed structurally so the
10
+ * option does not depend on which `typescript` package the caller's own type
11
+ * resolution lands on: under a `typescript@7` pin `typeof import("typescript")`
12
+ * is the native shell's version module, not the compiler API. The members are
13
+ * optional for the same reason — the shell has none of them — and
14
+ * `isTypeScriptCompilerModule` decides at runtime whether the module can parse.
15
+ */
16
+ export type TypeScriptCompilerModuleLike = {
17
+ readonly createSourceFile?: (...parameters: never[]) => unknown;
18
+ readonly ScriptTarget?: object;
19
+ readonly version?: string;
20
+ };
21
+
22
+ /**
23
+ * Package specifiers that may carry the compiler API, in resolution order.
24
+ *
25
+ * `typescript@7` (the Go-native toolchain) resolves but its JavaScript entry
26
+ * exports only `version`/`getExePath` — no `createSourceFile`, so the lint
27
+ * rules cannot parse with it. The compiler API of that generation is published
28
+ * as `@typescript/typescript6`, which is what a `typescript@7` dependency tree
29
+ * (for example the APIFuse monorepo root) installs alongside the shell.
30
+ */
31
+ export const TYPESCRIPT_COMPILER_MODULE_SPECIFIERS = [
32
+ "typescript",
33
+ "@typescript/typescript6",
34
+ ] as const;
35
+
36
+ /**
37
+ * True when `candidate` is a loaded module that exposes the parser the lint
38
+ * rules need. Internal (narrows to the `typescript` module type, which is not
39
+ * part of the package surface); `lintRuntimeBoundarySources` applies it to the
40
+ * caller-supplied option.
41
+ */
42
+ export function isTypeScriptCompilerModule(candidate: unknown): candidate is TypeScriptModule {
43
+ return (
44
+ typeof candidate === "object" &&
45
+ candidate !== null &&
46
+ typeof (candidate as { createSourceFile?: unknown }).createSourceFile === "function" &&
47
+ typeof (candidate as { ScriptTarget?: unknown }).ScriptTarget === "object"
48
+ );
49
+ }
50
+
51
+ function describeCandidate(candidate: unknown): string {
52
+ if (typeof candidate === "object" && candidate !== null) {
53
+ const version = (candidate as { version?: unknown }).version;
54
+ if (typeof version === "string") return `resolved ${version} without a compiler API`;
55
+ }
56
+ return "resolved without a compiler API";
57
+ }
58
+
59
+ /**
60
+ * Resolve the compiler API through `load`, trying each specifier in order and
61
+ * accepting the first module that exposes `createSourceFile`. Exposed for the
62
+ * tests; production code uses `getTypeScript()`.
63
+ */
64
+ export function loadTypeScriptModule(
65
+ load: (specifier: string) => unknown,
66
+ specifiers: readonly string[] = TYPESCRIPT_COMPILER_MODULE_SPECIFIERS,
67
+ ): TypeScriptModule {
68
+ const attempts: string[] = [];
69
+ for (const specifier of specifiers) {
70
+ let candidate: unknown;
71
+ try {
72
+ candidate = load(specifier);
73
+ } catch {
74
+ attempts.push(`${specifier}: not resolvable`);
75
+ continue;
76
+ }
77
+ if (isTypeScriptCompilerModule(candidate)) return candidate;
78
+ attempts.push(`${specifier}: ${describeCandidate(candidate)}`);
79
+ }
80
+ throw new Error(
81
+ `The provider source lint needs the TypeScript compiler API (createSourceFile) and none of the resolvable packages provide it — ${attempts.join("; ")}. Install typescript 6.x as a devDependency, or @typescript/typescript6 next to a typescript 7 toolchain, in the dependency tree that installs @apifuse/provider-sdk.`,
82
+ );
83
+ }
84
+
85
+ /**
86
+ * Lazily loaded TypeScript compiler API shared by the source-level lint rules.
87
+ *
88
+ * `typeof import(...)` keeps the type without emitting a static import: the
89
+ * typescript package is a devDependency of the SDK and only the CLI and the
90
+ * lint rules need it at runtime, which the typescript-import-boundary test
91
+ * enforces for production sources. Resolution starts at the installed SDK, so
92
+ * the caller's dependency tree must provide one of
93
+ * `TYPESCRIPT_COMPILER_MODULE_SPECIFIERS`.
94
+ */
95
+ let typeScriptModule: TypeScriptModule | undefined;
96
+
97
+ export function getTypeScript(): TypeScriptModule {
98
+ typeScriptModule ??= loadTypeScriptModule(requireModule);
99
+ return typeScriptModule;
100
+ }
@@ -1,24 +0,0 @@
1
- export type ProviderChoiceTokenPayload = Record<string, unknown>;
2
- export type ProviderChoiceTokenErrorReason = "invalid_shape" | "invalid_signature" | "invalid_payload" | "invalid_binding" | "stale";
3
- export declare class ProviderChoiceTokenError extends Error {
4
- readonly reason: ProviderChoiceTokenErrorReason;
5
- constructor(reason: ProviderChoiceTokenErrorReason, message: string);
6
- }
7
- export interface CreateProviderChoiceTokenOptions<TPayload extends ProviderChoiceTokenPayload> {
8
- prefix: string;
9
- payload: TPayload;
10
- secret: string;
11
- }
12
- export interface ParseProviderChoiceTokenOptions {
13
- token: string;
14
- prefix: string;
15
- secret: string;
16
- }
17
- export interface FreshProviderChoiceIssuedAtOptions {
18
- ttlMs: number;
19
- nowMs?: number;
20
- futureToleranceMs?: number;
21
- }
22
- export declare function createProviderChoiceToken<TPayload extends ProviderChoiceTokenPayload>(options: CreateProviderChoiceTokenOptions<TPayload>): string;
23
- export declare function parseProviderChoiceToken(options: ParseProviderChoiceTokenOptions): ProviderChoiceTokenPayload;
24
- export declare function assertFreshProviderChoiceIssuedAt(issuedAtMs: unknown, options: FreshProviderChoiceIssuedAtOptions): number;
@@ -1,74 +0,0 @@
1
- import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes, timingSafeEqual, } from "node:crypto";
2
- export class ProviderChoiceTokenError extends Error {
3
- reason;
4
- constructor(reason, message) {
5
- super(message);
6
- this.name = "ProviderChoiceTokenError";
7
- this.reason = reason;
8
- }
9
- }
10
- export function createProviderChoiceToken(options) {
11
- const iv = randomBytes(12);
12
- const cipher = createCipheriv("aes-256-gcm", choiceEncryptionKey(options.secret), iv);
13
- const encryptedPayload = Buffer.concat([
14
- cipher.update(JSON.stringify(options.payload), "utf8"),
15
- cipher.final(),
16
- ]).toString("base64url");
17
- const authTag = cipher.getAuthTag().toString("base64url");
18
- const encodedIv = iv.toString("base64url");
19
- const signature = signProviderChoiceTokenBody(`${options.prefix}.${encodedIv}.${encryptedPayload}.${authTag}`, options.secret);
20
- return `${options.prefix}.${encodedIv}.${encryptedPayload}.${authTag}.${signature}`;
21
- }
22
- export function parseProviderChoiceToken(options) {
23
- const [actualPrefix, encodedIv, encryptedPayload, authTag, signature, ...extra] = options.token.split(".");
24
- if (actualPrefix !== options.prefix ||
25
- !encodedIv ||
26
- !encryptedPayload ||
27
- !authTag ||
28
- !signature ||
29
- extra.length > 0) {
30
- throw new ProviderChoiceTokenError("invalid_shape", "Provider choice token shape is invalid.");
31
- }
32
- const signedBody = `${options.prefix}.${encodedIv}.${encryptedPayload}.${authTag}`;
33
- const expectedSignature = signProviderChoiceTokenBody(signedBody, options.secret);
34
- const actualBuffer = Buffer.from(signature);
35
- const expectedBuffer = Buffer.from(expectedSignature);
36
- if (actualBuffer.length !== expectedBuffer.length ||
37
- !timingSafeEqual(actualBuffer, expectedBuffer)) {
38
- throw new ProviderChoiceTokenError("invalid_signature", "Provider choice token signature is invalid.");
39
- }
40
- try {
41
- const decipher = createDecipheriv("aes-256-gcm", choiceEncryptionKey(options.secret), Buffer.from(encodedIv, "base64url"));
42
- decipher.setAuthTag(Buffer.from(authTag, "base64url"));
43
- const decrypted = Buffer.concat([
44
- decipher.update(Buffer.from(encryptedPayload, "base64url")),
45
- decipher.final(),
46
- ]).toString("utf8");
47
- const parsed = JSON.parse(decrypted);
48
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
49
- throw new Error("payload is not an object");
50
- }
51
- return Object.fromEntries(Object.entries(parsed));
52
- }
53
- catch {
54
- throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token payload is invalid.");
55
- }
56
- }
57
- export function assertFreshProviderChoiceIssuedAt(issuedAtMs, options) {
58
- const parsed = typeof issuedAtMs === "number" ? issuedAtMs : Number(issuedAtMs);
59
- const nowMs = options.nowMs ?? Date.now();
60
- const futureToleranceMs = options.futureToleranceMs ?? 30_000;
61
- if (!Number.isFinite(parsed) ||
62
- parsed <= 0 ||
63
- nowMs - parsed > options.ttlMs ||
64
- parsed - nowMs > futureToleranceMs) {
65
- throw new ProviderChoiceTokenError("stale", "Provider choice token is stale.");
66
- }
67
- return parsed;
68
- }
69
- function choiceEncryptionKey(secret) {
70
- return createHash("sha256").update(secret).digest();
71
- }
72
- function signProviderChoiceTokenBody(body, secret) {
73
- return createHmac("sha256", secret).update(body).digest("base64url");
74
- }
@@ -1,15 +0,0 @@
1
- import type { CredentialContext, EnvContext, ProviderChoiceContext, ProviderRequestContext, ProviderRuntimeState } from "../types.js";
2
- export declare const PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV = "APIFUSE__PROVIDER_RUNTIME__CHOICE_TOKEN_MASTER_SECRET";
3
- export type CreateProviderChoiceContextOptions = {
4
- readonly providerId: string;
5
- readonly env?: EnvContext;
6
- readonly request?: ProviderRequestContext;
7
- readonly credential?: CredentialContext;
8
- readonly state?: ProviderRuntimeState;
9
- readonly masterSecret?: string;
10
- readonly kid?: string;
11
- };
12
- export declare function createProviderChoiceContext(options: CreateProviderChoiceContextOptions): ProviderChoiceContext;
13
- export declare function createTestProviderChoiceContext(options: Omit<CreateProviderChoiceContextOptions, "masterSecret"> & {
14
- readonly masterSecret?: string;
15
- }): ProviderChoiceContext;
@@ -1,413 +0,0 @@
1
- import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes, timingSafeEqual, } from "node:crypto";
2
- import { assertFreshProviderChoiceIssuedAt, ProviderChoiceTokenError, } from "../choice-token.js";
3
- import { ProviderError } from "../errors.js";
4
- export const PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV = "APIFUSE__PROVIDER_RUNTIME__CHOICE_TOKEN_MASTER_SECRET";
5
- const PRIMARY_CHOICE_TOKEN_KID = "v1";
6
- const MANAGED_CHOICE_TOKEN_VERSION = 1;
7
- export function createProviderChoiceContext(options) {
8
- const kid = options.kid ?? PRIMARY_CHOICE_TOKEN_KID;
9
- const resolveMasterSecret = () => resolveChoiceMasterSecret(options);
10
- function issue(issueOptions) {
11
- const issuedAtMs = issueOptions.nowMs ?? Date.now();
12
- const keys = deriveManagedChoiceKeys({
13
- masterSecret: resolveMasterSecret(),
14
- providerId: options.providerId,
15
- purpose: issueOptions.purpose,
16
- kid,
17
- });
18
- const baseEnvelope = {
19
- v: MANAGED_CHOICE_TOKEN_VERSION,
20
- provider_id: options.providerId,
21
- purpose: issueOptions.purpose,
22
- issued_at_ms: issuedAtMs,
23
- ttl_ms: issueOptions.ttlMs,
24
- binding: createChoiceBinding({
25
- keys,
26
- options: issueOptions.bind,
27
- request: options.request,
28
- credential: options.credential,
29
- required: true,
30
- }),
31
- };
32
- const resolvedStorage = resolveIssueStorage(issueOptions.storage, issueOptions.payload);
33
- if (resolvedStorage.mode === "server") {
34
- return issueServerStoredChoice({
35
- baseEnvelope,
36
- issueOptions,
37
- storage: resolvedStorage.storage,
38
- contextState: options.state,
39
- kid,
40
- keys,
41
- issuedAtMs,
42
- });
43
- }
44
- const envelope = {
45
- ...baseEnvelope,
46
- payload: issueOptions.payload,
47
- };
48
- return encryptManagedChoiceToken({
49
- prefix: issueOptions.prefix,
50
- kid,
51
- envelope,
52
- keys,
53
- });
54
- }
55
- function parse(parseOptions) {
56
- const [actualPrefix, tokenKid, encodedIv, encryptedPayload, authTag, signature] = parseManagedChoiceTokenParts(parseOptions.token);
57
- if (actualPrefix !== parseOptions.prefix ||
58
- tokenKid !== kid ||
59
- !encodedIv ||
60
- !encryptedPayload ||
61
- !authTag ||
62
- !signature) {
63
- throw new ProviderChoiceTokenError("invalid_shape", "Provider choice token shape is invalid.");
64
- }
65
- const keys = deriveManagedChoiceKeys({
66
- masterSecret: resolveMasterSecret(),
67
- providerId: options.providerId,
68
- purpose: parseOptions.purpose,
69
- kid: tokenKid,
70
- });
71
- const signedBody = [parseOptions.prefix, tokenKid, encodedIv, encryptedPayload, authTag].join(".");
72
- assertManagedChoiceSignature({
73
- signedBody,
74
- signature,
75
- signingKey: keys.signing,
76
- });
77
- const envelope = decryptManagedChoiceToken({
78
- encodedIv,
79
- encryptedPayload,
80
- authTag,
81
- encryptionKey: keys.encryption,
82
- });
83
- assertManagedChoiceEnvelope(envelope, {
84
- providerId: options.providerId,
85
- purpose: parseOptions.purpose,
86
- ttlMs: parseOptions.ttlMs,
87
- nowMs: parseOptions.nowMs,
88
- futureToleranceMs: parseOptions.futureToleranceMs,
89
- });
90
- assertChoiceBindingMatches({
91
- actual: envelope.binding,
92
- expected: createChoiceBinding({
93
- keys,
94
- options: parseOptions.bind,
95
- request: options.request,
96
- credential: options.credential,
97
- required: true,
98
- }),
99
- });
100
- if (isServerChoiceHandlePayload(envelope.payload)) {
101
- return parseServerStoredChoice({
102
- handle: envelope.payload,
103
- storage: parseOptions.storage,
104
- contextState: options.state,
105
- });
106
- }
107
- return envelope.payload;
108
- }
109
- return { issue, parse };
110
- }
111
- export function createTestProviderChoiceContext(options) {
112
- return createProviderChoiceContext({
113
- ...options,
114
- masterSecret: options.masterSecret ?? "apifuse-test-provider-runtime-choice-token-master-secret",
115
- });
116
- }
117
- function resolveChoiceMasterSecret(options) {
118
- const configured = options.masterSecret ?? options.env?.get(PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV);
119
- const trimmed = configured?.trim();
120
- if (trimmed)
121
- return trimmed;
122
- throw new ProviderError("Provider runtime choice-token master secret is not configured.", {
123
- code: "CHOICE_TOKEN_MASTER_SECRET_NOT_CONFIGURED",
124
- category: "internal_error",
125
- retryable: false,
126
- details: {
127
- secret: PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
128
- },
129
- });
130
- }
131
- function deriveManagedChoiceKeys(input) {
132
- return {
133
- encryption: deriveManagedChoiceKey(input, "encryption"),
134
- signing: deriveManagedChoiceKey(input, "signing"),
135
- binding: deriveManagedChoiceKey(input, "binding"),
136
- };
137
- }
138
- function deriveManagedChoiceKey(input, usage) {
139
- return createHmac("sha256", input.masterSecret)
140
- .update("apifuse-provider-choice-token")
141
- .update("\0")
142
- .update(input.providerId)
143
- .update("\0")
144
- .update(input.purpose)
145
- .update("\0")
146
- .update(input.kid)
147
- .update("\0")
148
- .update(usage)
149
- .digest();
150
- }
151
- function encryptManagedChoiceToken(options) {
152
- const iv = randomBytes(12);
153
- const cipher = createCipheriv("aes-256-gcm", options.keys.encryption, iv);
154
- const encryptedPayload = Buffer.concat([
155
- cipher.update(JSON.stringify(options.envelope), "utf8"),
156
- cipher.final(),
157
- ]).toString("base64url");
158
- const authTag = cipher.getAuthTag().toString("base64url");
159
- const encodedIv = iv.toString("base64url");
160
- const signedBody = [options.prefix, options.kid, encodedIv, encryptedPayload, authTag].join(".");
161
- const signature = createHmac("sha256", options.keys.signing)
162
- .update(signedBody)
163
- .digest("base64url");
164
- return `${signedBody}.${signature}`;
165
- }
166
- async function issueServerStoredChoice(options) {
167
- const serializedPayload = serializeChoicePayload(options.issueOptions.payload);
168
- const payloadBytes = Buffer.byteLength(serializedPayload, "utf8");
169
- if (payloadBytes > options.storage.maxValueBytes) {
170
- throw new ProviderError("Provider choice payload exceeds state storage policy.", {
171
- code: "CHOICE_STATE_PAYLOAD_TOO_LARGE",
172
- category: "input_validation",
173
- retryable: false,
174
- details: {
175
- maxValueBytes: options.storage.maxValueBytes,
176
- payloadBytes,
177
- },
178
- });
179
- }
180
- const stateId = `choice_${randomBytes(16).toString("base64url")}`;
181
- const digest = digestChoicePayload(serializedPayload);
182
- const namespace = resolveChoiceStateNamespace({
183
- storage: options.storage,
184
- contextState: options.contextState,
185
- ttlMs: options.issueOptions.ttlMs,
186
- });
187
- await namespace.set(optionsStateKey(stateId), options.issueOptions.payload, {
188
- ttl: stateTtl(options.storage, options.issueOptions.ttlMs),
189
- });
190
- const envelope = {
191
- ...options.baseEnvelope,
192
- payload: {
193
- storage: "server",
194
- state_id: stateId,
195
- payload_digest: digest,
196
- created_at_ms: options.issuedAtMs,
197
- },
198
- };
199
- return encryptManagedChoiceToken({
200
- prefix: options.issueOptions.prefix,
201
- kid: options.kid,
202
- envelope,
203
- keys: options.keys,
204
- });
205
- }
206
- async function parseServerStoredChoice(options) {
207
- const storage = resolveParseStorage(options.storage);
208
- const namespace = resolveChoiceStateNamespace({
209
- storage,
210
- contextState: options.contextState,
211
- });
212
- const record = await namespace.get(optionsStateKey(options.handle.state_id));
213
- if (!record) {
214
- throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token state payload is missing.");
215
- }
216
- const serializedPayload = serializeChoicePayload(record.value);
217
- assertPayloadDigestMatches({
218
- actual: digestChoicePayload(serializedPayload),
219
- expected: options.handle.payload_digest,
220
- });
221
- return record.value;
222
- }
223
- function resolveIssueStorage(storage, payload) {
224
- if (!storage || storage.mode === "inline")
225
- return { mode: "inline" };
226
- if (storage.mode === "server")
227
- return { mode: "server", storage };
228
- const payloadBytes = Buffer.byteLength(serializeChoicePayload(payload), "utf8");
229
- if (payloadBytes <= storage.maxInlineBytes)
230
- return { mode: "inline" };
231
- return { mode: "server", storage };
232
- }
233
- function resolveParseStorage(storage) {
234
- if (!storage || storage.mode === "inline") {
235
- throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token requires server-side choice storage.");
236
- }
237
- return storage;
238
- }
239
- function resolveChoiceStateNamespace(options) {
240
- const state = options.storage.state ?? options.contextState;
241
- if (!state) {
242
- throw new ProviderError("Provider choice state storage is not available.", {
243
- code: "CHOICE_STATE_UNAVAILABLE",
244
- category: "internal_error",
245
- retryable: false,
246
- });
247
- }
248
- return state.namespace(options.storage.namespace, {
249
- defaultTtl: stateTtl(options.storage, options.ttlMs),
250
- maxTtl: stateTtl(options.storage, options.ttlMs),
251
- maxEntries: options.storage.maxEntries,
252
- maxValueBytes: options.storage.maxValueBytes,
253
- });
254
- }
255
- function stateTtl(storage, ttlMs) {
256
- return storage.ttl ?? `${ttlMs ?? 1}ms`;
257
- }
258
- function optionsStateKey(stateId) {
259
- return stateId;
260
- }
261
- function serializeChoicePayload(payload) {
262
- return JSON.stringify(payload);
263
- }
264
- function digestChoicePayload(serializedPayload) {
265
- return createHash("sha256").update(serializedPayload).digest("base64url");
266
- }
267
- function isServerChoiceHandlePayload(value) {
268
- return (value.storage === "server" &&
269
- typeof value.state_id === "string" &&
270
- typeof value.payload_digest === "string" &&
271
- typeof value.created_at_ms === "number");
272
- }
273
- function assertPayloadDigestMatches(options) {
274
- const actual = Buffer.from(options.actual);
275
- const expected = Buffer.from(options.expected);
276
- if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) {
277
- throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token state payload digest is invalid.");
278
- }
279
- }
280
- function parseManagedChoiceTokenParts(token) {
281
- const parts = token.split(".");
282
- if (parts.length !== 6) {
283
- throw new ProviderChoiceTokenError("invalid_shape", "Provider choice token shape is invalid.");
284
- }
285
- return [parts[0], parts[1], parts[2], parts[3], parts[4], parts[5]];
286
- }
287
- function assertManagedChoiceSignature(options) {
288
- const expected = createHmac("sha256", options.signingKey)
289
- .update(options.signedBody)
290
- .digest("base64url");
291
- const actualBuffer = Buffer.from(options.signature);
292
- const expectedBuffer = Buffer.from(expected);
293
- if (actualBuffer.length !== expectedBuffer.length ||
294
- !timingSafeEqual(actualBuffer, expectedBuffer)) {
295
- throw new ProviderChoiceTokenError("invalid_signature", "Provider choice token signature is invalid.");
296
- }
297
- }
298
- function decryptManagedChoiceToken(options) {
299
- try {
300
- const decipher = createDecipheriv("aes-256-gcm", options.encryptionKey, Buffer.from(options.encodedIv, "base64url"));
301
- decipher.setAuthTag(Buffer.from(options.authTag, "base64url"));
302
- const decrypted = Buffer.concat([
303
- decipher.update(Buffer.from(options.encryptedPayload, "base64url")),
304
- decipher.final(),
305
- ]).toString("utf8");
306
- const parsed = JSON.parse(decrypted);
307
- if (!isManagedChoiceEnvelope(parsed)) {
308
- throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token payload is invalid.");
309
- }
310
- return parsed;
311
- }
312
- catch (error) {
313
- if (error instanceof ProviderChoiceTokenError) {
314
- throw error;
315
- }
316
- throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token payload is invalid.");
317
- }
318
- }
319
- function isManagedChoiceEnvelope(value) {
320
- if (!value || typeof value !== "object" || Array.isArray(value))
321
- return false;
322
- if (!("payload" in value) || !isChoicePayload(value.payload))
323
- return false;
324
- return ("v" in value &&
325
- value.v === MANAGED_CHOICE_TOKEN_VERSION &&
326
- "provider_id" in value &&
327
- typeof value.provider_id === "string" &&
328
- "purpose" in value &&
329
- typeof value.purpose === "string" &&
330
- "issued_at_ms" in value &&
331
- typeof value.issued_at_ms === "number" &&
332
- "ttl_ms" in value &&
333
- typeof value.ttl_ms === "number" &&
334
- (!("binding" in value) || value.binding === undefined || isChoiceBinding(value.binding)));
335
- }
336
- function isChoicePayload(value) {
337
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
338
- }
339
- function isChoiceBinding(value) {
340
- if (!value || typeof value !== "object" || Array.isArray(value))
341
- return false;
342
- return ((!("connection_hash" in value) || typeof value.connection_hash === "string") &&
343
- (!("credential_hash" in value) || typeof value.credential_hash === "string"));
344
- }
345
- function assertManagedChoiceEnvelope(envelope, options) {
346
- if (envelope.provider_id !== options.providerId || envelope.purpose !== options.purpose) {
347
- throw new ProviderChoiceTokenError("invalid_payload", "Provider choice token payload is invalid.");
348
- }
349
- assertFreshProviderChoiceIssuedAt(envelope.issued_at_ms, {
350
- // Clamp to the issuer's embedded TTL so a caller-supplied value cannot
351
- // silently extend token validity past the deadline the issuer intended.
352
- ttlMs: options.ttlMs != null ? Math.min(options.ttlMs, envelope.ttl_ms) : envelope.ttl_ms,
353
- nowMs: options.nowMs,
354
- futureToleranceMs: options.futureToleranceMs,
355
- });
356
- }
357
- function createChoiceBinding(options) {
358
- const connectionHash = options.options?.connection ? hashRequiredConnection(options) : undefined;
359
- const credentialHash = options.options?.credentialKeys?.length
360
- ? hashCredentialKeys(options)
361
- : undefined;
362
- if (!connectionHash && !credentialHash)
363
- return undefined;
364
- return {
365
- ...(connectionHash ? { connection_hash: connectionHash } : {}),
366
- ...(credentialHash ? { credential_hash: credentialHash } : {}),
367
- };
368
- }
369
- function hashRequiredConnection(options) {
370
- const connectionId = options.request?.connectionId;
371
- if (!connectionId) {
372
- if (!options.required)
373
- return undefined;
374
- throw new ProviderError("Provider choice tokens require connection context.", {
375
- code: "CHOICE_CONTEXT_REQUIRED",
376
- category: "input_validation",
377
- retryable: false,
378
- });
379
- }
380
- return createHmac("sha256", options.keys.binding)
381
- .update("connection")
382
- .update("\0")
383
- .update(connectionId)
384
- .digest("base64url");
385
- }
386
- function hashCredentialKeys(options) {
387
- const credentialKeys = options.options?.credentialKeys ?? [];
388
- const material = credentialKeys.map((key) => {
389
- const value = options.credential?.get(key);
390
- if (typeof value !== "string" || value.length === 0) {
391
- throw new ProviderError("Provider choice tokens require configured credential binding.", {
392
- code: "CHOICE_CONTEXT_REQUIRED",
393
- category: "input_validation",
394
- retryable: false,
395
- details: { credentialKey: key },
396
- });
397
- }
398
- return [key, value];
399
- });
400
- return createHmac("sha256", options.keys.binding)
401
- .update("credential")
402
- .update("\0")
403
- .update(JSON.stringify(material))
404
- .digest("base64url");
405
- }
406
- function assertChoiceBindingMatches(options) {
407
- if (options.actual?.connection_hash !== options.expected?.connection_hash) {
408
- throw new ProviderChoiceTokenError("invalid_binding", "Provider choice token connection binding is invalid.");
409
- }
410
- if (options.actual?.credential_hash !== options.expected?.credential_hash) {
411
- throw new ProviderChoiceTokenError("invalid_binding", "Provider choice token credential binding is invalid.");
412
- }
413
- }