@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,81 @@
1
+ import { ProviderError } from "../../errors.js";
2
+ import type { ProviderResolverVendor } from "../../types.js";
3
+
4
+ /**
5
+ * Exact SDK-owned service hosts each vendor's adapter may reach through its bound
6
+ * transport, in addition to the provider's declared `allowedHosts`. This table is
7
+ * the trust boundary for `ResolverVendorAdapter.transportAllowedHosts`: a
8
+ * declaration outside its vendor's entry is rejected, whoever supplied the adapter.
9
+ * Only Hyper's observed-IP reflector rides the identity-bound transport (ADR-0008
10
+ * v1.1 amend, PR #251); every other vendor talks to its own service directly.
11
+ * Frozen at runtime, not just in the type: the Hyper adapter hands its entry out by
12
+ * reference as `transportAllowedHosts`, so a mutable table would let any holder of a
13
+ * registry adapter widen the boundary for every later adapter in the process.
14
+ */
15
+ export const RESOLVER_VENDOR_TRANSPORT_HOSTS = Object.freeze({
16
+ "2captcha": Object.freeze([] as const),
17
+ browser: Object.freeze([] as const),
18
+ capmonster: Object.freeze([] as const),
19
+ capsolver: Object.freeze([] as const),
20
+ custom: Object.freeze([] as const),
21
+ hypersolutions: Object.freeze(["ip.hypersolutions.co"] as const),
22
+ }) satisfies Readonly<Record<ProviderResolverVendor, readonly string[]>>;
23
+
24
+ export function normalizedResolverHostname(hostname: string): string {
25
+ return hostname.trim().toLowerCase().replace(/\.$/, "");
26
+ }
27
+
28
+ export function assertResolverHostAllowed(
29
+ targetUrl: string,
30
+ allowedHosts: readonly string[],
31
+ ): void {
32
+ let targetUrlObject: URL;
33
+ try {
34
+ targetUrlObject = new URL(targetUrl);
35
+ } catch {
36
+ throw new ProviderError("Resolver target URL is invalid", {
37
+ code: "RESOLVER_HOST_NOT_ALLOWED",
38
+ fix: "Use a valid URL whose exact hostname appears in the provider's allowedHosts declaration.",
39
+ });
40
+ }
41
+ if (targetUrlObject.protocol !== "http:" && targetUrlObject.protocol !== "https:") {
42
+ throw new ProviderError(`Resolver target URL scheme "${targetUrlObject.protocol}" is not allowed`, {
43
+ code: "RESOLVER_HOST_NOT_ALLOWED",
44
+ fix: "Use an http or https URL whose exact hostname appears in the provider's allowedHosts declaration.",
45
+ });
46
+ }
47
+ const targetHost = normalizedResolverHostname(targetUrlObject.hostname);
48
+
49
+ const isAllowed = allowedHosts.some((host) => {
50
+ const declaredHost = normalizedResolverHostname(host);
51
+ return declaredHost.length > 0 && !declaredHost.includes("*") && declaredHost === targetHost;
52
+ });
53
+ if (isAllowed) return;
54
+
55
+ throw new ProviderError(`Resolver target host "${targetHost}" is not declared`, {
56
+ code: "RESOLVER_HOST_NOT_ALLOWED",
57
+ fix: "Add the exact target hostname to the provider's allowedHosts declaration.",
58
+ });
59
+ }
60
+
61
+ export function assertResolverVendorTransportHosts(
62
+ vendor: ProviderResolverVendor,
63
+ declaredHosts: readonly string[],
64
+ ): void {
65
+ // A vendor id outside the table (only reachable from untyped callers) owns no hosts and
66
+ // is rejected below like any other overreach; `hasOwn` keeps prototype keys out too.
67
+ const ownedHosts: readonly string[] = Object.hasOwn(RESOLVER_VENDOR_TRANSPORT_HOSTS, vendor)
68
+ ? RESOLVER_VENDOR_TRANSPORT_HOSTS[vendor]
69
+ : [];
70
+ for (const declaredHost of declaredHosts) {
71
+ const normalizedHost = normalizedResolverHostname(declaredHost);
72
+ if (ownedHosts.some((host) => normalizedResolverHostname(host) === normalizedHost)) continue;
73
+ throw new ProviderError(
74
+ `Resolver vendor "${vendor}" may not declare transport host "${normalizedHost}"`,
75
+ {
76
+ code: "RESOLVER_VENDOR_HOST_NOT_ALLOWED",
77
+ fix: "Remove the host from transportAllowedHosts: an adapter reaches only the provider's allowedHosts plus the SDK-owned service hosts of its vendor.",
78
+ },
79
+ );
80
+ }
81
+ }
@@ -0,0 +1,480 @@
1
+ import { isIP } from "node:net";
2
+
3
+ import type { ChallengeSolution, ProviderChallenge } from "../../types.js";
4
+ import { recordPaidResolverCreate } from "../resolver-usage.js";
5
+ import type { TraceRecorder } from "../trace.js";
6
+ import { assertResolverHostAllowed, RESOLVER_VENDOR_TRANSPORT_HOSTS } from "./hosts.js";
7
+ import {
8
+ ResolverChallengeVerdictError,
9
+ type ResolverIdentity,
10
+ type ResolverPaidUsageContext,
11
+ type ResolverVendorAdapter,
12
+ type ResolverVendorTransport,
13
+ ResolverVendorUnavailableError,
14
+ } from "./types.js";
15
+
16
+ const HYPERSOLUTIONS_VENDOR_ID = "hypersolutions" as const;
17
+ const HYPER_SBSD_URL = "https://akm.hypersolutions.co/sbsd";
18
+ const HYPER_IP_URL = "https://ip.hypersolutions.co/ip";
19
+ /**
20
+ * Only the observed-IP reflector rides the bound transport: Hyper must see the
21
+ * egress address the upstream will see. The payload-generation POST carries no
22
+ * identity and goes direct, as in the measured zozotown source.
23
+ */
24
+ const HYPER_TRANSPORT_HOSTS = RESOLVER_VENDOR_TRANSPORT_HOSTS.hypersolutions;
25
+ const IP_RESPONSE_MAX_BYTES = 4_096;
26
+ /** Measured bound shared by the script, the Hyper envelope, and the payload submission. */
27
+ const BODY_MAX_BYTES = 1_000_000;
28
+
29
+ type HyperPhase = "measure_ip" | "fetch_script" | "generate_payload" | "post_payload";
30
+
31
+ export interface HypersolutionsResolverVendorOptions {
32
+ readonly apiKey?: string;
33
+ readonly timeoutMs?: number;
34
+ readonly allowedHosts: readonly string[];
35
+ /** Direct egress used only for the Hyper payload-generation POST. */
36
+ readonly fetchImpl?: typeof fetch;
37
+ }
38
+
39
+ export type AkamaiSbsdChallengeSolution = Extract<
40
+ ChallengeSolution,
41
+ { readonly form: "cookie_state" }
42
+ >;
43
+
44
+ export interface HypersolutionsResolverVendorAdapter extends ResolverVendorAdapter {
45
+ readonly id: "hypersolutions";
46
+ readonly requiresTransport: true;
47
+ readonly transportAllowedHosts: typeof HYPER_TRANSPORT_HOSTS;
48
+ solve(
49
+ challenge: ProviderChallenge,
50
+ identity: ResolverIdentity | undefined,
51
+ signal: AbortSignal,
52
+ traceRecorder?: TraceRecorder,
53
+ transport?: ResolverVendorTransport,
54
+ usage?: ResolverPaidUsageContext,
55
+ ): Promise<AkamaiSbsdChallengeSolution>;
56
+ }
57
+
58
+ type TransportResponse = Awaited<ReturnType<ResolverVendorTransport["fetch"]>>;
59
+
60
+ function headerValue(headers: Readonly<Record<string, string>>, name: string): string | undefined {
61
+ const target = name.toLowerCase();
62
+ return Object.entries(headers)
63
+ .find(([header]) => header.toLowerCase() === target)?.[1]
64
+ ?.trim();
65
+ }
66
+
67
+ function declaredLengthExceeds(declared: string | undefined, maxBytes: number): boolean {
68
+ return declared !== undefined && /^\d+$/u.test(declared) && BigInt(declared) > BigInt(maxBytes);
69
+ }
70
+
71
+ function transportFailure(phase: HyperPhase, cause?: unknown): ResolverVendorUnavailableError {
72
+ return new ResolverVendorUnavailableError(HYPERSOLUTIONS_VENDOR_ID, "transport_failure", {
73
+ phase,
74
+ ...(cause === undefined ? {} : { cause }),
75
+ });
76
+ }
77
+
78
+ function assertBoundedBody(response: TransportResponse, maxBytes: number, phase: HyperPhase): void {
79
+ if (
80
+ declaredLengthExceeds(headerValue(response.headers, "content-length"), maxBytes) ||
81
+ new TextEncoder().encode(response.body).byteLength > maxBytes
82
+ ) {
83
+ throw transportFailure(phase);
84
+ }
85
+ }
86
+
87
+ function requireSuccess(status: number, phase: HyperPhase): void {
88
+ if (status >= 200 && status < 300) return;
89
+ if (phase === "measure_ip" || phase === "generate_payload") {
90
+ // Hyper's own service: a rejected key is a credential fault, anything else is transport.
91
+ throw new ResolverVendorUnavailableError(
92
+ HYPERSOLUTIONS_VENDOR_ID,
93
+ status === 401 || status === 403 ? "missing_credentials" : "transport_failure",
94
+ { phase },
95
+ );
96
+ }
97
+ // The upstream refused the script GET or the payload POST: that is the challenge verdict.
98
+ throw new ResolverChallengeVerdictError(HYPERSOLUTIONS_VENDOR_ID, "solve_failed", { phase });
99
+ }
100
+
101
+ function parseObservedIp(body: string): string | undefined {
102
+ let value: unknown = body.trim();
103
+ try {
104
+ value = JSON.parse(body);
105
+ } catch {
106
+ // Hyper's reflector has returned both JSON and plain text in measured clients.
107
+ }
108
+ if (value && typeof value === "object" && !Array.isArray(value) && "ip" in value) {
109
+ value = value.ip;
110
+ }
111
+ if (typeof value !== "string") return undefined;
112
+ const candidate = value.trim();
113
+ return isIP(candidate) ? candidate : undefined;
114
+ }
115
+
116
+ function parsePayload(body: string): string | undefined {
117
+ try {
118
+ const parsed: unknown = JSON.parse(body);
119
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || !("payload" in parsed)) {
120
+ return undefined;
121
+ }
122
+ return typeof parsed.payload === "string" && parsed.payload.length > 0
123
+ ? parsed.payload
124
+ : undefined;
125
+ } catch {
126
+ return undefined;
127
+ }
128
+ }
129
+
130
+ function scriptExchangeUrls(
131
+ scriptUrl: string,
132
+ laterChallengeToken: string | undefined,
133
+ ): {
134
+ readonly fetchUrl: string;
135
+ readonly postUrl: string;
136
+ readonly uuid: string;
137
+ readonly indices: readonly number[];
138
+ } {
139
+ // `?v=&t=` is the hard SBSD variant and `?v=` is passive SBSD. A no-query
140
+ // Akamai script is a sensor-family artifact and stays outside this adapter.
141
+ const parsed = new URL(scriptUrl);
142
+ const uuid = parsed.searchParams.get("v")?.trim();
143
+ if (!uuid) {
144
+ throw new ResolverVendorUnavailableError(HYPERSOLUTIONS_VENDOR_ID, "missing_challenge_input", {
145
+ missingFields: ["scriptUrl"],
146
+ phase: "fetch_script",
147
+ });
148
+ }
149
+ const scriptToken = parsed.searchParams.get("t")?.trim();
150
+ const laterToken = laterChallengeToken?.trim();
151
+ if (scriptToken && laterToken) {
152
+ throw new ResolverVendorUnavailableError(HYPERSOLUTIONS_VENDOR_ID, "missing_challenge_input", {
153
+ missingFields: ["challengeToken"],
154
+ phase: "fetch_script",
155
+ });
156
+ }
157
+ // Clone the validated URL and only replace its query: reparsing `pathname`
158
+ // against `origin` would read a `//host/...` pathname as a network-path
159
+ // reference and swap the host that assertChallengeInput just admitted.
160
+ const fetchUrl = new URL(parsed);
161
+ fetchUrl.search = "";
162
+ fetchUrl.hash = "";
163
+ fetchUrl.searchParams.set("v", uuid);
164
+ if (scriptToken) fetchUrl.searchParams.set("t", scriptToken);
165
+ const postUrl = new URL(fetchUrl);
166
+ postUrl.search = "";
167
+ const postToken = laterToken || scriptToken;
168
+ if (postToken) postUrl.searchParams.set("t", postToken);
169
+ return {
170
+ fetchUrl: fetchUrl.toString(),
171
+ postUrl: postUrl.toString(),
172
+ uuid,
173
+ indices: postToken ? [0] : [0, 1],
174
+ };
175
+ }
176
+
177
+ function assertChallengeInput(
178
+ challenge: Extract<ProviderChallenge, { readonly kind: "akamai_sbsd" }>,
179
+ allowedHosts: readonly string[],
180
+ ): void {
181
+ const missingFields = [
182
+ ...(challenge.pageUrl.trim() ? [] : ["pageUrl"]),
183
+ ...(challenge.scriptUrl.trim() ? [] : ["scriptUrl"]),
184
+ ...(challenge.stateCookieName === "sbsd_o" || challenge.stateCookieName === "bm_so"
185
+ ? []
186
+ : ["stateCookieName"]),
187
+ ...(challenge.challengeToken === undefined || challenge.challengeToken.trim()
188
+ ? []
189
+ : ["challengeToken"]),
190
+ ];
191
+ if (missingFields.length > 0) {
192
+ throw new ResolverVendorUnavailableError(HYPERSOLUTIONS_VENDOR_ID, "missing_challenge_input", {
193
+ missingFields,
194
+ });
195
+ }
196
+ assertResolverHostAllowed(challenge.pageUrl, allowedHosts);
197
+ assertResolverHostAllowed(challenge.scriptUrl, allowedHosts);
198
+ if (new URL(challenge.pageUrl).origin !== new URL(challenge.scriptUrl).origin) {
199
+ // The state cookie is read for pageUrl and posted to scriptUrl; they must share an origin.
200
+ throw new ResolverVendorUnavailableError(HYPERSOLUTIONS_VENDOR_ID, "missing_challenge_input", {
201
+ missingFields: ["scriptUrl"],
202
+ });
203
+ }
204
+ }
205
+
206
+ async function boundFetch(
207
+ transport: ResolverVendorTransport,
208
+ url: string,
209
+ init: Parameters<ResolverVendorTransport["fetch"]>[1],
210
+ phase: HyperPhase,
211
+ ): Promise<TransportResponse> {
212
+ try {
213
+ return await transport.fetch(url, init);
214
+ } catch (cause) {
215
+ if (
216
+ cause instanceof ResolverVendorUnavailableError ||
217
+ cause instanceof ResolverChallengeVerdictError
218
+ ) {
219
+ throw cause;
220
+ }
221
+ // An abort is the caller's (or the adapter timeout's) verdict, not a transport fault.
222
+ if (init.signal.aborted) throw init.signal.reason ?? cause;
223
+ throw transportFailure(phase, cause);
224
+ }
225
+ }
226
+
227
+ async function readBoundedText(response: Response, maxBytes: number): Promise<string | undefined> {
228
+ if (declaredLengthExceeds(response.headers.get("content-length")?.trim(), maxBytes)) {
229
+ await response.body?.cancel();
230
+ return undefined;
231
+ }
232
+ if (!response.body) return "";
233
+ const reader = response.body.getReader();
234
+ const decoder = new TextDecoder();
235
+ let received = 0;
236
+ let text = "";
237
+ for (;;) {
238
+ const { done, value } = await reader.read();
239
+ if (done) break;
240
+ received += value.byteLength;
241
+ if (received > maxBytes) {
242
+ await reader.cancel();
243
+ return undefined;
244
+ }
245
+ text += decoder.decode(value, { stream: true });
246
+ }
247
+ return text + decoder.decode();
248
+ }
249
+
250
+ async function generatePayload(
251
+ fetchImpl: typeof fetch,
252
+ apiKey: string,
253
+ body: string,
254
+ signal: AbortSignal,
255
+ ): Promise<{ readonly status: number; readonly body: string | undefined }> {
256
+ try {
257
+ const response = await fetchImpl(HYPER_SBSD_URL, {
258
+ method: "POST",
259
+ headers: {
260
+ accept: "application/json",
261
+ "content-type": "application/json",
262
+ "x-api-key": apiKey,
263
+ },
264
+ body,
265
+ signal,
266
+ redirect: "error",
267
+ });
268
+ // A body that fails mid-read is as much a transport fault as a refused connection.
269
+ return { status: response.status, body: await readBoundedText(response, BODY_MAX_BYTES) };
270
+ } catch (cause) {
271
+ if (signal.aborted) throw signal.reason ?? cause;
272
+ throw transportFailure("generate_payload", cause);
273
+ }
274
+ }
275
+
276
+ export function createHypersolutionsResolverVendorAdapter(
277
+ options: HypersolutionsResolverVendorOptions,
278
+ ): HypersolutionsResolverVendorAdapter {
279
+ const apiKey = options.apiKey?.trim();
280
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
281
+ return {
282
+ id: HYPERSOLUTIONS_VENDOR_ID,
283
+ requiresTransport: true,
284
+ transportAllowedHosts: HYPER_TRANSPORT_HOSTS,
285
+ supports: (kind) => kind === "akamai_sbsd",
286
+ async solve(challenge, _identity, signal, traceRecorder, transport, usage) {
287
+ const timeoutController = new AbortController();
288
+ const operationSignal = options.timeoutMs
289
+ ? AbortSignal.any([signal, timeoutController.signal])
290
+ : signal;
291
+ const timeout = options.timeoutMs
292
+ ? setTimeout(
293
+ // A named reason lets the usage span record `timeout`, not a caller abort.
294
+ () => timeoutController.abort(new DOMException("Hyper solve timed out", "TimeoutError")),
295
+ options.timeoutMs,
296
+ )
297
+ : undefined;
298
+ const runPhase = <T>(phase: HyperPhase, fn: () => Promise<T>): Promise<T> =>
299
+ traceRecorder ? traceRecorder.runSpan(`resolver.vendor.${phase}`, fn) : fn();
300
+ try {
301
+ if (challenge.kind !== "akamai_sbsd") {
302
+ throw new ResolverVendorUnavailableError(HYPERSOLUTIONS_VENDOR_ID, "not_implemented");
303
+ }
304
+ if (!apiKey) {
305
+ throw new ResolverVendorUnavailableError(HYPERSOLUTIONS_VENDOR_ID, "missing_credentials");
306
+ }
307
+ if (!transport?.getCookie) {
308
+ throw new ResolverVendorUnavailableError(HYPERSOLUTIONS_VENDOR_ID, "missing_transport");
309
+ }
310
+ const sessionHeaders = transport.sessionHeaders;
311
+ const userAgent = sessionHeaders ? headerValue(sessionHeaders, "user-agent") : undefined;
312
+ const acceptLanguage = sessionHeaders
313
+ ? headerValue(sessionHeaders, "accept-language")
314
+ : undefined;
315
+ if (!sessionHeaders || !userAgent || !acceptLanguage) {
316
+ throw new ResolverVendorUnavailableError(
317
+ HYPERSOLUTIONS_VENDOR_ID,
318
+ "missing_client_profile",
319
+ );
320
+ }
321
+ assertChallengeInput(challenge, options.allowedHosts);
322
+ const exchange = scriptExchangeUrls(challenge.scriptUrl, challenge.challengeToken);
323
+
324
+ // Hyper documents /ip as an authenticated service request but does not
325
+ // publish an explicit exclusion from request quota. Meter conservatively.
326
+ const ip = await recordPaidResolverCreate({
327
+ traceRecorder,
328
+ vendor: HYPERSOLUTIONS_VENDOR_ID,
329
+ kind: challenge.kind,
330
+ endpoint: "hyper:ip",
331
+ signal: operationSignal,
332
+ usage,
333
+ create: () =>
334
+ runPhase("measure_ip", async () => {
335
+ const ipResponse = await boundFetch(
336
+ transport,
337
+ HYPER_IP_URL,
338
+ {
339
+ method: "GET",
340
+ headers: {
341
+ accept: "application/json, text/plain;q=0.9",
342
+ "x-api-key": apiKey,
343
+ },
344
+ signal: operationSignal,
345
+ redirect: "manual",
346
+ maxBodyBytes: IP_RESPONSE_MAX_BYTES,
347
+ },
348
+ "measure_ip",
349
+ );
350
+ requireSuccess(ipResponse.status, "measure_ip");
351
+ assertBoundedBody(ipResponse, IP_RESPONSE_MAX_BYTES, "measure_ip");
352
+ const observedIp = parseObservedIp(ipResponse.body);
353
+ if (!observedIp) throw transportFailure("measure_ip");
354
+ return observedIp;
355
+ }),
356
+ });
357
+
358
+ const scriptResponse = await runPhase("fetch_script", async () => {
359
+ const scriptResponse = await boundFetch(
360
+ transport,
361
+ exchange.fetchUrl,
362
+ {
363
+ method: "GET",
364
+ headers: { ...sessionHeaders, Referer: challenge.pageUrl },
365
+ signal: operationSignal,
366
+ redirect: "manual",
367
+ maxBodyBytes: BODY_MAX_BYTES,
368
+ },
369
+ "fetch_script",
370
+ );
371
+ requireSuccess(scriptResponse.status, "fetch_script");
372
+ assertBoundedBody(scriptResponse, BODY_MAX_BYTES, "fetch_script");
373
+ if (!scriptResponse.body) {
374
+ throw new ResolverChallengeVerdictError(HYPERSOLUTIONS_VENDOR_ID, "solve_failed", {
375
+ phase: "fetch_script",
376
+ });
377
+ }
378
+ return scriptResponse;
379
+ });
380
+ const stateCookie = transport
381
+ .getCookie(challenge.stateCookieName, challenge.pageUrl)
382
+ ?.trim();
383
+ if (!stateCookie) {
384
+ throw new ResolverVendorUnavailableError(
385
+ HYPERSOLUTIONS_VENDOR_ID,
386
+ "missing_challenge_input",
387
+ { missingFields: [challenge.stateCookieName], phase: "fetch_script" },
388
+ );
389
+ }
390
+
391
+ let expires: number | undefined;
392
+ for (const [roundIndex, index] of exchange.indices.entries()) {
393
+ const round = roundIndex + 1;
394
+ const payload = await recordPaidResolverCreate({
395
+ traceRecorder,
396
+ vendor: HYPERSOLUTIONS_VENDOR_ID,
397
+ kind: challenge.kind,
398
+ endpoint: "hyper:sbsd_create",
399
+ round,
400
+ signal: operationSignal,
401
+ usage,
402
+ create: () =>
403
+ runPhase("generate_payload", async () => {
404
+ const hyperResponse = await generatePayload(
405
+ fetchImpl,
406
+ apiKey,
407
+ JSON.stringify({
408
+ index,
409
+ uuid: exchange.uuid,
410
+ o: stateCookie,
411
+ pageUrl: challenge.pageUrl,
412
+ userAgent,
413
+ script: scriptResponse.body,
414
+ ip,
415
+ acceptLanguage,
416
+ }),
417
+ operationSignal,
418
+ );
419
+ requireSuccess(hyperResponse.status, "generate_payload");
420
+ const generated =
421
+ hyperResponse.body === undefined ? undefined : parsePayload(hyperResponse.body);
422
+ if (!generated) {
423
+ throw new ResolverVendorUnavailableError(
424
+ HYPERSOLUTIONS_VENDOR_ID,
425
+ "transport_failure",
426
+ { phase: "generate_payload", round },
427
+ );
428
+ }
429
+ return generated;
430
+ }),
431
+ });
432
+ const postResponse = await runPhase("post_payload", async () => {
433
+ const postResponse = await boundFetch(
434
+ transport,
435
+ exchange.postUrl,
436
+ {
437
+ method: "POST",
438
+ headers: {
439
+ ...sessionHeaders,
440
+ "content-type": "application/json",
441
+ Referer: challenge.pageUrl,
442
+ },
443
+ body: JSON.stringify({ body: payload }),
444
+ signal: operationSignal,
445
+ redirect: "manual",
446
+ maxBodyBytes: BODY_MAX_BYTES,
447
+ },
448
+ "post_payload",
449
+ );
450
+ requireSuccess(postResponse.status, "post_payload");
451
+ assertBoundedBody(postResponse, BODY_MAX_BYTES, "post_payload");
452
+ return postResponse;
453
+ });
454
+ expires =
455
+ postResponse.cookies.find((cookie) => cookie.name === challenge.stateCookieName)
456
+ ?.expires ?? expires;
457
+ }
458
+
459
+ // A 2xx payload POST is not proof of a solve and the state cookie is not
460
+ // required to rotate (measured zozotown source and Hyper's docs both verify
461
+ // only through the next protected GET, which is Phase 2).
462
+ return {
463
+ form: "cookie_state",
464
+ kind: "akamai_sbsd",
465
+ outcome: "payload_accepted",
466
+ verified: false,
467
+ stateCookieName: challenge.stateCookieName,
468
+ ...(expires === undefined ? {} : { expires }),
469
+ };
470
+ } catch (error) {
471
+ if (timeoutController.signal.aborted && !signal.aborted) {
472
+ throw new ResolverVendorUnavailableError(HYPERSOLUTIONS_VENDOR_ID, "timeout");
473
+ }
474
+ throw error;
475
+ } finally {
476
+ if (timeout !== undefined) clearTimeout(timeout);
477
+ }
478
+ },
479
+ };
480
+ }