@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,544 @@
1
+ import { getStealthProfile } from "../../stealth/profiles.js";
2
+ import { redactSensitiveText } from "../request-options.js";
3
+ import { DEFAULT_STEALTH_PROFILE } from "../stealth.js";
4
+ import { recordPaidResolverCreate } from "../resolver-usage.js";
5
+ import { resolverSpanAttributes } from "../resolver-span-attributes.js";
6
+ import { assertResolverHostAllowed } from "./hosts.js";
7
+ import { ResolverChallengeVerdictError, ResolverVendorUnavailableError, recordResolverVendorPoll, resolverVendorSupports, } from "./types.js";
8
+ const CAPSOLVER_VENDOR_ID = "capsolver";
9
+ const DEFAULT_CAPSOLVER_BASE_URL = "https://api.capsolver.com";
10
+ const DEFAULT_POLL_INTERVAL_MS = 2_000;
11
+ const DEFAULT_TIMEOUT_MS = 120_000;
12
+ const SDK_ESTIMATED_COOKIE_TTL_MS_BY_CHALLENGE_KIND = {
13
+ // CapSolver omits expiry, so use one conservative hour despite measured
14
+ // AWS WAF lifetimes of days.
15
+ aws_waf: 60 * 60 * 1_000,
16
+ };
17
+ class CapsolverSolveTimeoutError extends Error {
18
+ constructor() {
19
+ super("Capsolver resolver solve budget elapsed");
20
+ this.name = "CapsolverSolveTimeoutError";
21
+ }
22
+ }
23
+ class CapsolverUnavailableError extends ResolverVendorUnavailableError {
24
+ errorCode;
25
+ errorDescription;
26
+ responseStatus;
27
+ responseContentType;
28
+ responseLength;
29
+ constructor(reason, options) {
30
+ super(CAPSOLVER_VENDOR_ID, reason, options);
31
+ this.errorCode = options.errorCode;
32
+ this.errorDescription = options.errorDescription;
33
+ this.responseStatus = options.responseStatus;
34
+ this.responseContentType = options.responseContentType;
35
+ this.responseLength = options.responseLength;
36
+ }
37
+ }
38
+ class CapsolverVerdictError extends ResolverChallengeVerdictError {
39
+ phase;
40
+ errorCode;
41
+ errorDescription;
42
+ constructor(options) {
43
+ super(CAPSOLVER_VENDOR_ID, "solve_failed", options);
44
+ this.phase = options.phase;
45
+ this.errorCode = options.errorCode;
46
+ this.errorDescription = options.errorDescription;
47
+ }
48
+ }
49
+ function isJsonRecord(value) {
50
+ return value !== null && typeof value === "object" && !Array.isArray(value);
51
+ }
52
+ function abortReason(signal) {
53
+ return signal.reason ?? new DOMException("The operation was aborted", "AbortError");
54
+ }
55
+ function containsSensitiveValue(value, sensitiveValues) {
56
+ const secrets = sensitiveValues.filter((secret) => secret.length > 0);
57
+ if (secrets.length === 0)
58
+ return false;
59
+ const seen = new Set();
60
+ const inspect = (candidate) => {
61
+ if (typeof candidate === "string") {
62
+ return secrets.some((secret) => candidate.includes(secret));
63
+ }
64
+ if (candidate === null || (typeof candidate !== "object" && typeof candidate !== "function")) {
65
+ return false;
66
+ }
67
+ if (seen.has(candidate))
68
+ return false;
69
+ seen.add(candidate);
70
+ try {
71
+ for (const property of Reflect.ownKeys(candidate)) {
72
+ if (typeof property === "string" && inspect(property))
73
+ return true;
74
+ const descriptor = Object.getOwnPropertyDescriptor(candidate, property);
75
+ if (!descriptor)
76
+ return true;
77
+ if ("value" in descriptor && inspect(descriptor.value))
78
+ return true;
79
+ if (descriptor.get !== undefined || descriptor.set !== undefined)
80
+ return true;
81
+ }
82
+ }
83
+ catch {
84
+ return true;
85
+ }
86
+ return false;
87
+ };
88
+ return inspect(value);
89
+ }
90
+ function safeCauseOptions(error, sensitiveValues) {
91
+ return containsSensitiveValue(error, sensitiveValues) ? {} : { cause: error };
92
+ }
93
+ function sanitizedJsonParseCause() {
94
+ return new SyntaxError("Upstream response failed");
95
+ }
96
+ function raceWithAbort(operation, signal, phase, sensitiveValues = []) {
97
+ if (signal.aborted)
98
+ return Promise.reject(abortReason(signal));
99
+ return new Promise((resolve, reject) => {
100
+ const cleanup = () => signal.removeEventListener("abort", onAbort);
101
+ const onAbort = () => {
102
+ cleanup();
103
+ reject(abortReason(signal));
104
+ };
105
+ signal.addEventListener("abort", onAbort, { once: true });
106
+ operation().then((value) => {
107
+ cleanup();
108
+ resolve(value);
109
+ }, (error) => {
110
+ cleanup();
111
+ if (phase === undefined) {
112
+ reject(error);
113
+ return;
114
+ }
115
+ reject(new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "transport_failure", {
116
+ ...safeCauseOptions(error, sensitiveValues),
117
+ phase,
118
+ }));
119
+ });
120
+ });
121
+ }
122
+ async function abortableDelay(ms, signal) {
123
+ let timer;
124
+ try {
125
+ await raceWithAbort(() => new Promise((resolve) => {
126
+ timer = setTimeout(resolve, ms);
127
+ }), signal);
128
+ }
129
+ finally {
130
+ if (timer !== undefined)
131
+ clearTimeout(timer);
132
+ }
133
+ }
134
+ function responseErrorFields(payload) {
135
+ return {
136
+ errorId: typeof payload.errorId === "number" ? payload.errorId : undefined,
137
+ errorCode: typeof payload.errorCode === "string" ? payload.errorCode : undefined,
138
+ errorDescription: typeof payload.errorDescription === "string" ? payload.errorDescription : undefined,
139
+ };
140
+ }
141
+ function parseCreateTaskResponse(payload) {
142
+ const taskId = payload.taskId;
143
+ return {
144
+ ...responseErrorFields(payload),
145
+ taskId: typeof taskId === "string" || typeof taskId === "number" ? taskId : undefined,
146
+ };
147
+ }
148
+ function parsePollResultResponse(payload) {
149
+ const solution = isJsonRecord(payload.solution) ? payload.solution : undefined;
150
+ const cookies = solution && isJsonRecord(solution.cookies)
151
+ ? Object.fromEntries(Object.entries(solution.cookies).filter((entry) => typeof entry[1] === "string"))
152
+ : undefined;
153
+ return {
154
+ ...responseErrorFields(payload),
155
+ status: typeof payload.status === "string" ? payload.status : undefined,
156
+ solution: solution
157
+ ? {
158
+ token: typeof solution.token === "string" ? solution.token : undefined,
159
+ cookie: typeof solution.cookie === "string" ? solution.cookie : undefined,
160
+ gRecaptchaResponse: typeof solution.gRecaptchaResponse === "string"
161
+ ? solution.gRecaptchaResponse
162
+ : undefined,
163
+ cookies,
164
+ userAgent: typeof solution.userAgent === "string" ? solution.userAgent : undefined,
165
+ }
166
+ : undefined,
167
+ };
168
+ }
169
+ function proxyForCapsolver(proxyUrl) {
170
+ try {
171
+ const url = new URL(proxyUrl);
172
+ const protocol = url.protocol.slice(0, -1).toLowerCase();
173
+ const scheme = protocol === "http" || protocol === "socks5" ? protocol : undefined;
174
+ const port = Number(url.port || (scheme === "socks5" ? 1080 : 80));
175
+ if (!scheme || !url.hostname || !Number.isInteger(port) || port <= 0 || port > 65_535) {
176
+ return undefined;
177
+ }
178
+ const username = url.username ? decodeURIComponent(url.username) : "";
179
+ const password = url.password ? decodeURIComponent(url.password) : "";
180
+ if (username.includes(":") || password.includes(":"))
181
+ return undefined;
182
+ const value = `${scheme}:${url.hostname}:${port}${username || password ? `:${username}:${password}` : ""}`;
183
+ return { value, sensitive: [proxyUrl, value, username, password].filter(Boolean) };
184
+ }
185
+ catch {
186
+ return undefined;
187
+ }
188
+ }
189
+ function isAllocationExhausted(payload) {
190
+ const code = payload.errorCode?.toLowerCase() ?? "";
191
+ const description = payload.errorDescription?.toLowerCase() ?? "";
192
+ return (code === "error_zero_balance" ||
193
+ /(?:insufficient|zero|no|not enough)\s+(?:balance|funds|credit)/u.test(`${code} ${description}`));
194
+ }
195
+ function isNegativeVerdict(payload) {
196
+ return payload.errorCode?.toLowerCase() === "error_captcha_unsolvable";
197
+ }
198
+ function safeVendorDetail(value, sensitiveValues) {
199
+ const redacted = redactSensitiveText(value, sensitiveValues);
200
+ return containsSensitiveValue(redacted, sensitiveValues) ? "[REDACTED]" : redacted;
201
+ }
202
+ function vendorErrorDetails(payload, sensitiveValues) {
203
+ const errorCode = payload.errorCode?.trim();
204
+ const errorDescription = payload.errorDescription?.trim();
205
+ return {
206
+ ...(errorCode ? { errorCode: safeVendorDetail(errorCode, sensitiveValues) } : {}),
207
+ ...(errorDescription
208
+ ? { errorDescription: safeVendorDetail(payload.errorDescription ?? "", sensitiveValues) }
209
+ : {}),
210
+ };
211
+ }
212
+ function unavailableForPayload(payload, phase, sensitiveValues) {
213
+ const details = vendorErrorDetails(payload, sensitiveValues);
214
+ if (isNegativeVerdict(payload)) {
215
+ return new CapsolverVerdictError({ phase, ...details });
216
+ }
217
+ return new CapsolverUnavailableError(isAllocationExhausted(payload) ? "allocation_exhausted" : "transport_failure", { phase, ...details });
218
+ }
219
+ async function postJson(fetchImpl, url, body, signal, phase, sensitiveValues, parseResponse) {
220
+ const response = await raceWithAbort(() => fetchImpl(url, {
221
+ method: "POST",
222
+ headers: { "content-type": "application/json" },
223
+ body: JSON.stringify(body),
224
+ signal,
225
+ redirect: "error",
226
+ }), signal, phase, sensitiveValues);
227
+ let responseText;
228
+ try {
229
+ responseText = await raceWithAbort(() => response.text(), signal, phase, sensitiveValues);
230
+ }
231
+ catch (error) {
232
+ if (error instanceof ResolverVendorUnavailableError)
233
+ throw error;
234
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "transport_failure", {
235
+ cause: error,
236
+ phase,
237
+ });
238
+ }
239
+ let payload;
240
+ try {
241
+ payload = JSON.parse(responseText);
242
+ }
243
+ catch {
244
+ const contentType = response.headers.get("content-type");
245
+ throw new CapsolverUnavailableError("transport_failure", {
246
+ cause: sanitizedJsonParseCause(),
247
+ phase,
248
+ responseStatus: response.status,
249
+ responseContentType: contentType
250
+ ? safeVendorDetail(contentType.slice(0, 128), sensitiveValues)
251
+ : undefined,
252
+ responseLength: responseText.length,
253
+ });
254
+ }
255
+ if (!isJsonRecord(payload)) {
256
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "transport_failure", {
257
+ phase,
258
+ });
259
+ }
260
+ return { ok: response.ok, payload: parseResponse(payload) };
261
+ }
262
+ function endpoint(baseUrl, path) {
263
+ return `${baseUrl.replace(/\/+$/u, "")}/${path}`;
264
+ }
265
+ function spanErrorAttributes(error, phase) {
266
+ if (error instanceof ResolverVendorUnavailableError) {
267
+ return resolverSpanAttributes({
268
+ unavailability_reason: error.reason,
269
+ transport_phase: error.phase,
270
+ ...(error instanceof CapsolverUnavailableError
271
+ ? {
272
+ vendor_error_code: error.errorCode,
273
+ vendor_error_description: error.errorDescription,
274
+ response_status: error.responseStatus,
275
+ response_content_type: error.responseContentType,
276
+ response_length: error.responseLength,
277
+ }
278
+ : {}),
279
+ });
280
+ }
281
+ if (error instanceof CapsolverVerdictError) {
282
+ return resolverSpanAttributes({
283
+ verdict_reason: error.reason,
284
+ transport_phase: error.phase,
285
+ vendor_error_code: error.errorCode,
286
+ vendor_error_description: error.errorDescription,
287
+ });
288
+ }
289
+ if (error instanceof CapsolverSolveTimeoutError) {
290
+ return resolverSpanAttributes({
291
+ unavailability_reason: "timeout",
292
+ transport_phase: phase,
293
+ });
294
+ }
295
+ return undefined;
296
+ }
297
+ export function createCapsolverResolverVendorAdapter(options) {
298
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
299
+ const baseUrl = options.baseUrl ?? DEFAULT_CAPSOLVER_BASE_URL;
300
+ const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
301
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
302
+ const now = options.now ?? Date.now;
303
+ const delay = options.delay ?? abortableDelay;
304
+ return {
305
+ id: CAPSOLVER_VENDOR_ID,
306
+ supports(kind) {
307
+ return resolverVendorSupports(CAPSOLVER_VENDOR_ID, kind);
308
+ },
309
+ async solve(challenge, identity, callerSignal, traceRecorder, _transport, usage) {
310
+ const apiKey = options.apiKey?.trim();
311
+ if (!apiKey) {
312
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "missing_credentials", {
313
+ phase: "create_task",
314
+ });
315
+ }
316
+ if (!resolverVendorSupports(CAPSOLVER_VENDOR_ID, challenge.kind)) {
317
+ throw new TypeError(`Capsolver resolver does not support ${challenge.kind}`);
318
+ }
319
+ const proxy = identity ? proxyForCapsolver(identity.proxyUrl) : undefined;
320
+ if (challenge.kind === "cloudflare_interstitial" && !identity) {
321
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "missing_proxy_identity", {
322
+ phase: "create_task",
323
+ });
324
+ }
325
+ if (challenge.kind !== "aws_waf" && identity && !proxy) {
326
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "transport_failure", {
327
+ phase: "create_task",
328
+ });
329
+ }
330
+ const challengeFields = challenge;
331
+ const sensitiveValues = [
332
+ apiKey,
333
+ challenge.pageUrl,
334
+ ...(typeof challengeFields.siteKey === "string" ? [challengeFields.siteKey] : []),
335
+ ...(typeof challengeFields.action === "string" ? [challengeFields.action] : []),
336
+ ...(typeof challengeFields.cdata === "string" ? [challengeFields.cdata] : []),
337
+ ...(typeof challengeFields.blockedHtml === "string" ? [challengeFields.blockedHtml] : []),
338
+ ...(typeof challengeFields.captchaScript === "string" ? [challengeFields.captchaScript] : []),
339
+ ...(typeof challengeFields.context === "string" ? [challengeFields.context] : []),
340
+ ...(typeof challengeFields.iv === "string" ? [challengeFields.iv] : []),
341
+ ...(proxy?.sensitive ?? []),
342
+ ];
343
+ assertResolverHostAllowed(challenge.pageUrl, options.allowedHosts);
344
+ callerSignal.throwIfAborted();
345
+ const solveController = new AbortController();
346
+ const onCallerAbort = () => solveController.abort(abortReason(callerSignal));
347
+ callerSignal.addEventListener("abort", onCallerAbort, { once: true });
348
+ const timeout = options.now
349
+ ? undefined
350
+ : setTimeout(() => solveController.abort(new CapsolverSolveTimeoutError()), timeoutMs);
351
+ const startedAt = now();
352
+ let phase = "create_task";
353
+ try {
354
+ const createTask = async () => {
355
+ // AWS WAF tokens are portable (ADR 0006 lease A→B), so minting can use solver
356
+ // egress independently of the redemption proxy. Passing the caller proxy makes
357
+ // allowlisted allocators such as Smartproxy reject solver workers with
358
+ // "custom proxy connect failed" (production measurement, 2026-09-02).
359
+ const task = challenge.kind === "aws_waf"
360
+ ? {
361
+ type: "AntiAwsWafTaskProxyLess",
362
+ websiteURL: challenge.pageUrl,
363
+ ...(challenge.siteKey !== undefined ? { awsKey: challenge.siteKey } : {}),
364
+ ...(challenge.iv !== undefined ? { awsIv: challenge.iv } : {}),
365
+ ...(challenge.context !== undefined ? { awsContext: challenge.context } : {}),
366
+ ...(challenge.captchaScript !== undefined
367
+ ? { awsChallengeJS: challenge.captchaScript }
368
+ : {}),
369
+ ...(identity?.userAgent ? { userAgent: identity.userAgent } : {}),
370
+ }
371
+ : challenge.kind === "turnstile"
372
+ ? {
373
+ type: "AntiTurnstileTaskProxyLess",
374
+ websiteURL: challenge.pageUrl,
375
+ websiteKey: challenge.siteKey,
376
+ ...(challenge.action !== undefined || challenge.cdata !== undefined
377
+ ? {
378
+ metadata: {
379
+ ...(challenge.action !== undefined ? { action: challenge.action } : {}),
380
+ ...(challenge.cdata !== undefined ? { cdata: challenge.cdata } : {}),
381
+ },
382
+ }
383
+ : {}),
384
+ }
385
+ : challenge.kind === "recaptcha_v2"
386
+ ? {
387
+ type: proxy ? "ReCaptchaV2Task" : "ReCaptchaV2TaskProxyLess",
388
+ websiteURL: challenge.pageUrl,
389
+ websiteKey: challenge.siteKey,
390
+ ...(proxy ? { proxy: proxy.value } : {}),
391
+ }
392
+ : challenge.kind === "recaptcha_v3"
393
+ ? {
394
+ type: proxy ? "ReCaptchaV3Task" : "ReCaptchaV3TaskProxyLess",
395
+ websiteURL: challenge.pageUrl,
396
+ websiteKey: challenge.siteKey,
397
+ pageAction: challenge.action,
398
+ ...(challenge.minScore !== undefined ? { minScore: challenge.minScore } : {}),
399
+ ...(proxy ? { proxy: proxy.value } : {}),
400
+ }
401
+ : challenge.kind === "hcaptcha"
402
+ ? {
403
+ type: proxy ? "HCaptchaTask" : "HCaptchaTaskProxyLess",
404
+ websiteURL: challenge.pageUrl,
405
+ websiteKey: challenge.siteKey,
406
+ ...(proxy ? { proxy: proxy.value } : {}),
407
+ }
408
+ : challenge.kind === "cloudflare_interstitial"
409
+ ? {
410
+ type: "AntiCloudflareTask",
411
+ websiteURL: challenge.pageUrl,
412
+ proxy: proxy?.value,
413
+ ...(identity?.userAgent ? { userAgent: identity.userAgent } : {}),
414
+ ...(challenge.kind === "cloudflare_interstitial" && challenge.blockedHtml !== undefined
415
+ ? { html: challenge.blockedHtml }
416
+ : {}),
417
+ }
418
+ : (() => {
419
+ throw new TypeError(`Capsolver resolver does not support ${challenge.kind}`);
420
+ })();
421
+ return await recordPaidResolverCreate({
422
+ traceRecorder,
423
+ vendor: CAPSOLVER_VENDOR_ID,
424
+ kind: challenge.kind,
425
+ endpoint: "capsolver:create_task",
426
+ signal: solveController.signal,
427
+ usage,
428
+ create: async () => {
429
+ const createResult = await postJson(fetchImpl, endpoint(baseUrl, "createTask"), { clientKey: apiKey, task }, solveController.signal, phase, sensitiveValues, parseCreateTaskResponse);
430
+ const taskId = createResult.payload.taskId;
431
+ if (!createResult.ok || createResult.payload.errorId !== 0 || taskId === undefined) {
432
+ throw unavailableForPayload(createResult.payload, phase, sensitiveValues);
433
+ }
434
+ return taskId;
435
+ },
436
+ });
437
+ };
438
+ const taskId = traceRecorder
439
+ ? await traceRecorder.runSpan("resolver.vendor.create_task", createTask, {
440
+ attributes: resolverSpanAttributes({
441
+ vendor: CAPSOLVER_VENDOR_ID,
442
+ challenge_kind: challenge.kind,
443
+ }),
444
+ onError: (error) => spanErrorAttributes(error, "create_task"),
445
+ })
446
+ : await createTask();
447
+ phase = "poll_result";
448
+ const pollResult = async () => {
449
+ while (true) {
450
+ callerSignal.throwIfAborted();
451
+ const remainingMs = timeoutMs - (now() - startedAt);
452
+ if (remainingMs <= 0)
453
+ throw new CapsolverSolveTimeoutError();
454
+ await delay(Math.min(pollIntervalMs, remainingMs), solveController.signal);
455
+ callerSignal.throwIfAborted();
456
+ if (now() - startedAt >= timeoutMs)
457
+ throw new CapsolverSolveTimeoutError();
458
+ recordResolverVendorPoll(traceRecorder);
459
+ const result = await postJson(fetchImpl, endpoint(baseUrl, "getTaskResult"), { clientKey: apiKey, taskId }, solveController.signal, phase, sensitiveValues, parsePollResultResponse);
460
+ if (!result.ok || result.payload.errorId !== 0) {
461
+ throw unavailableForPayload(result.payload, phase, sensitiveValues);
462
+ }
463
+ switch (result.payload.status) {
464
+ case "idle":
465
+ case "processing":
466
+ continue;
467
+ case "ready":
468
+ break;
469
+ default:
470
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "transport_failure", {
471
+ phase,
472
+ });
473
+ }
474
+ const solutionValue = challenge.kind === "aws_waf"
475
+ ? result.payload.solution?.cookie
476
+ : (result.payload.solution?.token ?? result.payload.solution?.gRecaptchaResponse);
477
+ if (challenge.kind === "cloudflare_interstitial") {
478
+ const cookies = result.payload.solution?.cookies;
479
+ const clearance = cookies?.cf_clearance ?? solutionValue;
480
+ if (!clearance?.trim()) {
481
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "transport_failure", {
482
+ phase,
483
+ });
484
+ }
485
+ return {
486
+ form: "cookies",
487
+ cookies: cookies && Object.keys(cookies).length > 0 ? cookies : { cf_clearance: clearance },
488
+ userAgent: result.payload.solution?.userAgent ??
489
+ identity?.userAgent ??
490
+ getStealthProfile(DEFAULT_STEALTH_PROFILE).userAgent,
491
+ };
492
+ }
493
+ if (!solutionValue?.trim()) {
494
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "transport_failure", {
495
+ phase,
496
+ });
497
+ }
498
+ return challenge.kind === "aws_waf"
499
+ ? {
500
+ form: "cookies",
501
+ cookies: { "aws-waf-token": solutionValue },
502
+ userAgent: identity?.userAgent ?? getStealthProfile(DEFAULT_STEALTH_PROFILE).userAgent,
503
+ sdkEstimatedExpires: (now() + SDK_ESTIMATED_COOKIE_TTL_MS_BY_CHALLENGE_KIND.aws_waf) / 1_000,
504
+ }
505
+ : { form: "token", token: solutionValue };
506
+ }
507
+ };
508
+ return traceRecorder
509
+ ? await traceRecorder.runSpan("resolver.vendor.poll_result", pollResult, {
510
+ attributes: resolverSpanAttributes({
511
+ vendor: CAPSOLVER_VENDOR_ID,
512
+ challenge_kind: challenge.kind,
513
+ }),
514
+ onError: (error) => spanErrorAttributes(error, "poll_result"),
515
+ })
516
+ : await pollResult();
517
+ }
518
+ catch (error) {
519
+ if (callerSignal.aborted)
520
+ throw abortReason(callerSignal);
521
+ if (error instanceof CapsolverSolveTimeoutError ||
522
+ solveController.signal.reason instanceof CapsolverSolveTimeoutError) {
523
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "timeout", {
524
+ cause: error,
525
+ phase,
526
+ });
527
+ }
528
+ if (error instanceof ResolverVendorUnavailableError ||
529
+ error instanceof ResolverChallengeVerdictError) {
530
+ throw error;
531
+ }
532
+ throw new ResolverVendorUnavailableError(CAPSOLVER_VENDOR_ID, "transport_failure", {
533
+ ...safeCauseOptions(error, sensitiveValues),
534
+ phase,
535
+ });
536
+ }
537
+ finally {
538
+ if (timeout !== undefined)
539
+ clearTimeout(timeout);
540
+ callerSignal.removeEventListener("abort", onCallerAbort);
541
+ }
542
+ },
543
+ };
544
+ }
@@ -0,0 +1,23 @@
1
+ import type { ProviderResolverVendor } from "../../types.js";
2
+ /**
3
+ * Exact SDK-owned service hosts each vendor's adapter may reach through its bound
4
+ * transport, in addition to the provider's declared `allowedHosts`. This table is
5
+ * the trust boundary for `ResolverVendorAdapter.transportAllowedHosts`: a
6
+ * declaration outside its vendor's entry is rejected, whoever supplied the adapter.
7
+ * Only Hyper's observed-IP reflector rides the identity-bound transport (ADR-0008
8
+ * v1.1 amend, PR #251); every other vendor talks to its own service directly.
9
+ * Frozen at runtime, not just in the type: the Hyper adapter hands its entry out by
10
+ * reference as `transportAllowedHosts`, so a mutable table would let any holder of a
11
+ * registry adapter widen the boundary for every later adapter in the process.
12
+ */
13
+ export declare const RESOLVER_VENDOR_TRANSPORT_HOSTS: Readonly<{
14
+ "2captcha": readonly [];
15
+ browser: readonly [];
16
+ capmonster: readonly [];
17
+ capsolver: readonly [];
18
+ custom: readonly [];
19
+ hypersolutions: readonly ["ip.hypersolutions.co"];
20
+ }>;
21
+ export declare function normalizedResolverHostname(hostname: string): string;
22
+ export declare function assertResolverHostAllowed(targetUrl: string, allowedHosts: readonly string[]): void;
23
+ export declare function assertResolverVendorTransportHosts(vendor: ProviderResolverVendor, declaredHosts: readonly string[]): void;
@@ -0,0 +1,68 @@
1
+ import { ProviderError } from "../../errors.js";
2
+ /**
3
+ * Exact SDK-owned service hosts each vendor's adapter may reach through its bound
4
+ * transport, in addition to the provider's declared `allowedHosts`. This table is
5
+ * the trust boundary for `ResolverVendorAdapter.transportAllowedHosts`: a
6
+ * declaration outside its vendor's entry is rejected, whoever supplied the adapter.
7
+ * Only Hyper's observed-IP reflector rides the identity-bound transport (ADR-0008
8
+ * v1.1 amend, PR #251); every other vendor talks to its own service directly.
9
+ * Frozen at runtime, not just in the type: the Hyper adapter hands its entry out by
10
+ * reference as `transportAllowedHosts`, so a mutable table would let any holder of a
11
+ * registry adapter widen the boundary for every later adapter in the process.
12
+ */
13
+ export const RESOLVER_VENDOR_TRANSPORT_HOSTS = Object.freeze({
14
+ "2captcha": Object.freeze([]),
15
+ browser: Object.freeze([]),
16
+ capmonster: Object.freeze([]),
17
+ capsolver: Object.freeze([]),
18
+ custom: Object.freeze([]),
19
+ hypersolutions: Object.freeze(["ip.hypersolutions.co"]),
20
+ });
21
+ export function normalizedResolverHostname(hostname) {
22
+ return hostname.trim().toLowerCase().replace(/\.$/, "");
23
+ }
24
+ export function assertResolverHostAllowed(targetUrl, allowedHosts) {
25
+ let targetUrlObject;
26
+ try {
27
+ targetUrlObject = new URL(targetUrl);
28
+ }
29
+ catch {
30
+ throw new ProviderError("Resolver target URL is invalid", {
31
+ code: "RESOLVER_HOST_NOT_ALLOWED",
32
+ fix: "Use a valid URL whose exact hostname appears in the provider's allowedHosts declaration.",
33
+ });
34
+ }
35
+ if (targetUrlObject.protocol !== "http:" && targetUrlObject.protocol !== "https:") {
36
+ throw new ProviderError(`Resolver target URL scheme "${targetUrlObject.protocol}" is not allowed`, {
37
+ code: "RESOLVER_HOST_NOT_ALLOWED",
38
+ fix: "Use an http or https URL whose exact hostname appears in the provider's allowedHosts declaration.",
39
+ });
40
+ }
41
+ const targetHost = normalizedResolverHostname(targetUrlObject.hostname);
42
+ const isAllowed = allowedHosts.some((host) => {
43
+ const declaredHost = normalizedResolverHostname(host);
44
+ return declaredHost.length > 0 && !declaredHost.includes("*") && declaredHost === targetHost;
45
+ });
46
+ if (isAllowed)
47
+ return;
48
+ throw new ProviderError(`Resolver target host "${targetHost}" is not declared`, {
49
+ code: "RESOLVER_HOST_NOT_ALLOWED",
50
+ fix: "Add the exact target hostname to the provider's allowedHosts declaration.",
51
+ });
52
+ }
53
+ export function assertResolverVendorTransportHosts(vendor, declaredHosts) {
54
+ // A vendor id outside the table (only reachable from untyped callers) owns no hosts and
55
+ // is rejected below like any other overreach; `hasOwn` keeps prototype keys out too.
56
+ const ownedHosts = Object.hasOwn(RESOLVER_VENDOR_TRANSPORT_HOSTS, vendor)
57
+ ? RESOLVER_VENDOR_TRANSPORT_HOSTS[vendor]
58
+ : [];
59
+ for (const declaredHost of declaredHosts) {
60
+ const normalizedHost = normalizedResolverHostname(declaredHost);
61
+ if (ownedHosts.some((host) => normalizedResolverHostname(host) === normalizedHost))
62
+ continue;
63
+ throw new ProviderError(`Resolver vendor "${vendor}" may not declare transport host "${normalizedHost}"`, {
64
+ code: "RESOLVER_VENDOR_HOST_NOT_ALLOWED",
65
+ fix: "Remove the host from transportAllowedHosts: an adapter reaches only the provider's allowedHosts plus the SDK-owned service hosts of its vendor.",
66
+ });
67
+ }
68
+ }
@@ -0,0 +1,27 @@
1
+ import type { ChallengeSolution, ProviderChallenge } from "../../types.js";
2
+ import type { TraceRecorder } from "../trace.js";
3
+ import { type ResolverIdentity, type ResolverPaidUsageContext, type ResolverVendorAdapter, type ResolverVendorTransport } from "./types.js";
4
+ /**
5
+ * Only the observed-IP reflector rides the bound transport: Hyper must see the
6
+ * egress address the upstream will see. The payload-generation POST carries no
7
+ * identity and goes direct, as in the measured zozotown source.
8
+ */
9
+ declare const HYPER_TRANSPORT_HOSTS: readonly ["ip.hypersolutions.co"];
10
+ export interface HypersolutionsResolverVendorOptions {
11
+ readonly apiKey?: string;
12
+ readonly timeoutMs?: number;
13
+ readonly allowedHosts: readonly string[];
14
+ /** Direct egress used only for the Hyper payload-generation POST. */
15
+ readonly fetchImpl?: typeof fetch;
16
+ }
17
+ export type AkamaiSbsdChallengeSolution = Extract<ChallengeSolution, {
18
+ readonly form: "cookie_state";
19
+ }>;
20
+ export interface HypersolutionsResolverVendorAdapter extends ResolverVendorAdapter {
21
+ readonly id: "hypersolutions";
22
+ readonly requiresTransport: true;
23
+ readonly transportAllowedHosts: typeof HYPER_TRANSPORT_HOSTS;
24
+ solve(challenge: ProviderChallenge, identity: ResolverIdentity | undefined, signal: AbortSignal, traceRecorder?: TraceRecorder, transport?: ResolverVendorTransport, usage?: ResolverPaidUsageContext): Promise<AkamaiSbsdChallengeSolution>;
25
+ }
26
+ export declare function createHypersolutionsResolverVendorAdapter(options: HypersolutionsResolverVendorOptions): HypersolutionsResolverVendorAdapter;
27
+ export {};