@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,425 @@
1
+ import { recordPaidResolverCreate } from "../resolver-usage.js";
2
+ import { resolverSpanAttributes } from "../resolver-span-attributes.js";
3
+ import { assertResolverHostAllowed } from "./hosts.js";
4
+ import { ResolverChallengeVerdictError, ResolverVendorUnavailableError, recordResolverVendorPoll, resolverVendorSupports, } from "./types.js";
5
+ const TWOCAPTCHA_VENDOR_ID = "2captcha";
6
+ const DEFAULT_TWOCAPTCHA_BASE_URL = "https://api.2captcha.com";
7
+ const DEFAULT_POLL_INTERVAL_MS = 3_000;
8
+ const DEFAULT_TIMEOUT_MS = 180_000;
9
+ class TwoCaptchaSolveTimeoutError extends Error {
10
+ constructor() {
11
+ super("2captcha resolver solve budget elapsed");
12
+ this.name = "TwoCaptchaSolveTimeoutError";
13
+ }
14
+ }
15
+ function isJsonRecord(value) {
16
+ return value !== null && typeof value === "object" && !Array.isArray(value);
17
+ }
18
+ function abortReason(signal) {
19
+ return signal.reason ?? new DOMException("The operation was aborted", "AbortError");
20
+ }
21
+ function containsSensitiveValue(value, sensitiveValues) {
22
+ const secrets = sensitiveValues.filter((secret) => secret.length > 0);
23
+ if (secrets.length === 0)
24
+ return false;
25
+ const seen = new Set();
26
+ const inspect = (candidate) => {
27
+ if (typeof candidate === "string") {
28
+ return secrets.some((secret) => candidate.includes(secret));
29
+ }
30
+ if (candidate === null ||
31
+ (typeof candidate !== "object" && typeof candidate !== "function")) {
32
+ return false;
33
+ }
34
+ if (seen.has(candidate))
35
+ return false;
36
+ seen.add(candidate);
37
+ try {
38
+ for (const property of Reflect.ownKeys(candidate)) {
39
+ if (typeof property === "string" && inspect(property))
40
+ return true;
41
+ const descriptor = Object.getOwnPropertyDescriptor(candidate, property);
42
+ if (!descriptor)
43
+ return true;
44
+ if ("value" in descriptor && inspect(descriptor.value))
45
+ return true;
46
+ if (descriptor.get !== undefined || descriptor.set !== undefined)
47
+ return true;
48
+ }
49
+ }
50
+ catch {
51
+ return true;
52
+ }
53
+ return false;
54
+ };
55
+ return inspect(value);
56
+ }
57
+ function safeCauseOptions(error, sensitiveValues) {
58
+ return containsSensitiveValue(error, sensitiveValues) ? {} : { cause: error };
59
+ }
60
+ function raceWithAbort(operation, signal, phase, sensitiveValues = []) {
61
+ if (signal.aborted)
62
+ return Promise.reject(abortReason(signal));
63
+ return new Promise((resolve, reject) => {
64
+ const cleanup = () => signal.removeEventListener("abort", onAbort);
65
+ const onAbort = () => {
66
+ cleanup();
67
+ reject(abortReason(signal));
68
+ };
69
+ signal.addEventListener("abort", onAbort, { once: true });
70
+ operation().then((value) => {
71
+ cleanup();
72
+ resolve(value);
73
+ }, (error) => {
74
+ cleanup();
75
+ if (phase === undefined) {
76
+ reject(error);
77
+ return;
78
+ }
79
+ reject(new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "transport_failure", {
80
+ ...safeCauseOptions(error, sensitiveValues),
81
+ phase,
82
+ }));
83
+ });
84
+ });
85
+ }
86
+ async function abortableDelay(ms, signal) {
87
+ let timer;
88
+ try {
89
+ await raceWithAbort(() => new Promise((resolve) => {
90
+ timer = setTimeout(resolve, ms);
91
+ }), signal);
92
+ }
93
+ finally {
94
+ if (timer !== undefined)
95
+ clearTimeout(timer);
96
+ }
97
+ }
98
+ function parseProxyConfiguration(proxyUrl) {
99
+ try {
100
+ const url = new URL(proxyUrl);
101
+ const protocol = url.protocol.slice(0, -1).toLowerCase();
102
+ const proxyType = protocol === "socks4" || protocol === "socks5"
103
+ ? protocol
104
+ : protocol === "http" || protocol === "https"
105
+ ? "http"
106
+ : undefined;
107
+ const defaultPort = proxyType === "http" ? 80 : 1080;
108
+ const proxyPort = Number(url.port || defaultPort);
109
+ if (!proxyType || !url.hostname || !Number.isInteger(proxyPort) || proxyPort <= 0) {
110
+ return undefined;
111
+ }
112
+ const proxyLogin = url.username ? decodeURIComponent(url.username) : undefined;
113
+ const proxyPassword = url.password ? decodeURIComponent(url.password) : undefined;
114
+ return {
115
+ proxyType,
116
+ proxyAddress: url.hostname,
117
+ proxyPort,
118
+ ...(proxyLogin ? { proxyLogin } : {}),
119
+ ...(proxyPassword ? { proxyPassword } : {}),
120
+ };
121
+ }
122
+ catch {
123
+ return undefined;
124
+ }
125
+ }
126
+ function errorText(payload, key) {
127
+ const value = payload[key];
128
+ return typeof value === "string" ? value : "";
129
+ }
130
+ function isAllocationExhausted(payload) {
131
+ const code = errorText(payload, "errorCode").toLowerCase();
132
+ const description = errorText(payload, "errorDescription").toLowerCase();
133
+ return (code === "error_zero_balance" ||
134
+ /(?:insufficient|zero|no|not enough)\s+(?:balance|funds|credit)/u.test(`${code} ${description}`));
135
+ }
136
+ function isNegativeVerdict(payload) {
137
+ return errorText(payload, "errorCode").toLowerCase() === "error_captcha_unsolvable";
138
+ }
139
+ function unavailableForPayload(payload, phase) {
140
+ if (isNegativeVerdict(payload)) {
141
+ return new ResolverChallengeVerdictError(TWOCAPTCHA_VENDOR_ID, "solve_failed");
142
+ }
143
+ return new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, isAllocationExhausted(payload) ? "allocation_exhausted" : "transport_failure", { phase });
144
+ }
145
+ async function postJson(fetchImpl, url, body, signal, phase, sensitiveValues) {
146
+ const response = await raceWithAbort(() => fetchImpl(url, {
147
+ method: "POST",
148
+ headers: { "content-type": "application/json" },
149
+ body: JSON.stringify(body),
150
+ signal,
151
+ redirect: "error",
152
+ }), signal, phase, sensitiveValues);
153
+ let responseText;
154
+ try {
155
+ responseText = await raceWithAbort(() => response.text(), signal, phase);
156
+ }
157
+ catch (error) {
158
+ if (error instanceof ResolverVendorUnavailableError)
159
+ throw error;
160
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "transport_failure", {
161
+ cause: error,
162
+ phase,
163
+ });
164
+ }
165
+ let payload;
166
+ try {
167
+ payload = JSON.parse(responseText);
168
+ }
169
+ catch {
170
+ // JSON parse errors may contain response-body excerpts, so do not retain them as causes.
171
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "transport_failure", {
172
+ phase,
173
+ });
174
+ }
175
+ if (!isJsonRecord(payload)) {
176
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "transport_failure", {
177
+ phase,
178
+ });
179
+ }
180
+ return { ok: response.ok, payload };
181
+ }
182
+ function taskIdFrom(payload) {
183
+ const taskId = payload.taskId;
184
+ return typeof taskId === "string" || typeof taskId === "number" ? taskId : undefined;
185
+ }
186
+ function tokenFrom(payload, challenge) {
187
+ const solution = payload.solution;
188
+ if (!isJsonRecord(solution))
189
+ return undefined;
190
+ if (challenge.kind === "aws_waf") {
191
+ return typeof solution.existing_token === "string" ? solution.existing_token : undefined;
192
+ }
193
+ if (typeof solution.gRecaptchaResponse === "string")
194
+ return solution.gRecaptchaResponse;
195
+ return typeof solution.token === "string" ? solution.token : undefined;
196
+ }
197
+ function endpoint(baseUrl, path) {
198
+ return `${baseUrl.replace(/\/+$/u, "")}/${path}`;
199
+ }
200
+ function spanErrorAttributes(error, phase) {
201
+ if (error instanceof ResolverVendorUnavailableError) {
202
+ return resolverSpanAttributes({
203
+ unavailability_reason: error.reason,
204
+ transport_phase: error.phase,
205
+ });
206
+ }
207
+ // The solve budget raises TwoCaptchaSolveTimeoutError inside the spanned closure and
208
+ // the outer catch converts it only after the span has been finalized, so the span has
209
+ // to recognize it here or slow solves lose exactly the attribution these spans add.
210
+ if (error instanceof TwoCaptchaSolveTimeoutError) {
211
+ return resolverSpanAttributes({
212
+ unavailability_reason: "timeout",
213
+ transport_phase: phase,
214
+ });
215
+ }
216
+ return undefined;
217
+ }
218
+ export function createTwoCaptchaResolverVendorAdapter(options) {
219
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
220
+ const baseUrl = options.baseUrl ?? DEFAULT_TWOCAPTCHA_BASE_URL;
221
+ const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
222
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
223
+ const now = options.now ?? Date.now;
224
+ const delay = options.delay ?? abortableDelay;
225
+ return {
226
+ id: TWOCAPTCHA_VENDOR_ID,
227
+ supports(kind) {
228
+ return resolverVendorSupports(TWOCAPTCHA_VENDOR_ID, kind);
229
+ },
230
+ async solve(challenge, identity, callerSignal, traceRecorder, _transport, usage) {
231
+ const apiKey = options.apiKey?.trim();
232
+ if (!apiKey) {
233
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "missing_credentials", {
234
+ phase: "create_task",
235
+ });
236
+ }
237
+ if (!resolverVendorSupports(TWOCAPTCHA_VENDOR_ID, challenge.kind)) {
238
+ throw new TypeError(`2captcha resolver does not support ${challenge.kind}`);
239
+ }
240
+ if (challenge.kind === "aws_waf") {
241
+ const missingFields = [
242
+ ...(challenge.siteKey?.trim() ? [] : ["siteKey"]),
243
+ ...(challenge.captchaScript?.trim() ? [] : ["captchaScript"]),
244
+ ...(challenge.context?.trim() ? [] : ["context"]),
245
+ ...(challenge.iv?.trim() ? [] : ["iv"]),
246
+ ];
247
+ if (missingFields.length > 0) {
248
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "missing_challenge_input", {
249
+ missingFields,
250
+ phase: "create_task",
251
+ });
252
+ }
253
+ }
254
+ if (challenge.kind === "recaptcha_v3" && challenge.minScore === undefined) {
255
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "missing_challenge_input", {
256
+ missingFields: ["minScore"],
257
+ phase: "create_task",
258
+ });
259
+ }
260
+ assertResolverHostAllowed(challenge.pageUrl, options.allowedHosts);
261
+ callerSignal.throwIfAborted();
262
+ const proxy = identity ? parseProxyConfiguration(identity.proxyUrl) : undefined;
263
+ if (identity && !proxy) {
264
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "transport_failure", {
265
+ phase: "create_task",
266
+ });
267
+ }
268
+ const solveController = new AbortController();
269
+ const onCallerAbort = () => solveController.abort(abortReason(callerSignal));
270
+ callerSignal.addEventListener("abort", onCallerAbort, { once: true });
271
+ const timeout = options.now
272
+ ? undefined
273
+ : setTimeout(() => solveController.abort(new TwoCaptchaSolveTimeoutError()), timeoutMs);
274
+ const startedAt = now();
275
+ let phase = "create_task";
276
+ try {
277
+ const createTask = async () => {
278
+ const task = challenge.kind === "aws_waf"
279
+ ? {
280
+ type: proxy ? "AmazonTask" : "AmazonTaskProxyless",
281
+ websiteURL: challenge.pageUrl,
282
+ websiteKey: challenge.siteKey,
283
+ captchaScript: challenge.captchaScript,
284
+ context: challenge.context,
285
+ iv: challenge.iv,
286
+ ...(identity ? { userAgent: identity.userAgent } : {}),
287
+ ...(proxy ?? {}),
288
+ }
289
+ : challenge.kind === "recaptcha_v2"
290
+ ? {
291
+ type: proxy ? "RecaptchaV2Task" : "RecaptchaV2TaskProxyless",
292
+ websiteURL: challenge.pageUrl,
293
+ websiteKey: challenge.siteKey,
294
+ isInvisible: false,
295
+ ...(identity ? { userAgent: identity.userAgent } : {}),
296
+ ...(proxy ?? {}),
297
+ }
298
+ : challenge.kind === "recaptcha_v3"
299
+ ? {
300
+ type: "RecaptchaV3TaskProxyless",
301
+ websiteURL: challenge.pageUrl,
302
+ websiteKey: challenge.siteKey,
303
+ minScore: challenge.minScore,
304
+ pageAction: challenge.action,
305
+ ...(identity ? { userAgent: identity.userAgent } : {}),
306
+ }
307
+ : challenge.kind === "hcaptcha"
308
+ ? {
309
+ type: proxy ? "HCaptchaTask" : "HCaptchaTaskProxyless",
310
+ websiteURL: challenge.pageUrl,
311
+ websiteKey: challenge.siteKey,
312
+ ...(identity ? { userAgent: identity.userAgent } : {}),
313
+ ...(proxy ?? {}),
314
+ }
315
+ : challenge.kind === "turnstile"
316
+ ? {
317
+ type: proxy ? "TurnstileTask" : "TurnstileTaskProxyless",
318
+ websiteURL: challenge.pageUrl,
319
+ websiteKey: challenge.siteKey,
320
+ ...(challenge.action !== undefined ? { action: challenge.action } : {}),
321
+ ...(challenge.cdata !== undefined ? { data: challenge.cdata } : {}),
322
+ ...(identity ? { userAgent: identity.userAgent } : {}),
323
+ ...(proxy ?? {}),
324
+ }
325
+ : // `resolverVendorSupports` above already rejected every kind this
326
+ // adapter does not build a task for, so this branch is unreachable.
327
+ (() => {
328
+ throw new TypeError(`2captcha resolver does not support ${challenge.kind}`);
329
+ })();
330
+ return await recordPaidResolverCreate({
331
+ traceRecorder,
332
+ vendor: TWOCAPTCHA_VENDOR_ID,
333
+ kind: challenge.kind,
334
+ endpoint: "twocaptcha:create_task",
335
+ signal: solveController.signal,
336
+ usage,
337
+ create: async () => {
338
+ const createResult = await postJson(fetchImpl, endpoint(baseUrl, "createTask"), { clientKey: apiKey, task }, solveController.signal, phase, [apiKey]);
339
+ const taskId = taskIdFrom(createResult.payload);
340
+ if (!createResult.ok || createResult.payload.errorId !== 0 || taskId === undefined) {
341
+ throw unavailableForPayload(createResult.payload, phase);
342
+ }
343
+ return taskId;
344
+ },
345
+ });
346
+ };
347
+ const taskId = traceRecorder
348
+ ? await traceRecorder.runSpan("resolver.vendor.create_task", createTask, {
349
+ attributes: resolverSpanAttributes({
350
+ vendor: TWOCAPTCHA_VENDOR_ID,
351
+ challenge_kind: challenge.kind,
352
+ }),
353
+ onError: (error) => spanErrorAttributes(error, "create_task"),
354
+ })
355
+ : await createTask();
356
+ phase = "poll_result";
357
+ const pollResult = async () => {
358
+ while (true) {
359
+ callerSignal.throwIfAborted();
360
+ const remainingMs = timeoutMs - (now() - startedAt);
361
+ if (remainingMs <= 0)
362
+ throw new TwoCaptchaSolveTimeoutError();
363
+ await delay(Math.min(pollIntervalMs, remainingMs), solveController.signal);
364
+ callerSignal.throwIfAborted();
365
+ if (now() - startedAt >= timeoutMs)
366
+ throw new TwoCaptchaSolveTimeoutError();
367
+ recordResolverVendorPoll(traceRecorder);
368
+ const pollResult = await postJson(fetchImpl, endpoint(baseUrl, "getTaskResult"), { clientKey: apiKey, taskId }, solveController.signal, phase, [apiKey]);
369
+ if (!pollResult.ok || pollResult.payload.errorId !== 0) {
370
+ throw unavailableForPayload(pollResult.payload, phase);
371
+ }
372
+ if (pollResult.payload.status === "processing")
373
+ continue;
374
+ if (pollResult.payload.status !== "ready") {
375
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "transport_failure", {
376
+ phase,
377
+ });
378
+ }
379
+ const token = tokenFrom(pollResult.payload, challenge);
380
+ if (!token?.trim()) {
381
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "transport_failure", {
382
+ phase,
383
+ });
384
+ }
385
+ // AWS WAF remains a token solution here, so resolver cookie caching does not apply.
386
+ return { form: "token", token };
387
+ }
388
+ };
389
+ return traceRecorder
390
+ ? await traceRecorder.runSpan("resolver.vendor.poll_result", pollResult, {
391
+ attributes: resolverSpanAttributes({
392
+ vendor: TWOCAPTCHA_VENDOR_ID,
393
+ challenge_kind: challenge.kind,
394
+ }),
395
+ onError: (error) => spanErrorAttributes(error, "poll_result"),
396
+ })
397
+ : await pollResult();
398
+ }
399
+ catch (error) {
400
+ if (callerSignal.aborted)
401
+ throw abortReason(callerSignal);
402
+ if (error instanceof TwoCaptchaSolveTimeoutError ||
403
+ solveController.signal.reason instanceof TwoCaptchaSolveTimeoutError) {
404
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "timeout", {
405
+ cause: error,
406
+ phase,
407
+ });
408
+ }
409
+ if (error instanceof ResolverVendorUnavailableError ||
410
+ error instanceof ResolverChallengeVerdictError) {
411
+ throw error;
412
+ }
413
+ throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "transport_failure", {
414
+ ...safeCauseOptions(error, [apiKey]),
415
+ phase,
416
+ });
417
+ }
418
+ finally {
419
+ if (timeout !== undefined)
420
+ clearTimeout(timeout);
421
+ callerSignal.removeEventListener("abort", onCallerAbort);
422
+ }
423
+ },
424
+ };
425
+ }
@@ -0,0 +1,125 @@
1
+ import type { ChallengeSolution, ProviderChallenge, ProviderChallengeKind, ProviderResolverConfig, ProviderResolverVendor } from "../../types.js";
2
+ import type { TraceRecorder } from "../trace.js";
3
+ /** Internal chain-runner hook; vendor adapters never receive the telemetry sink itself. */
4
+ export declare function recordResolverVendorPoll(traceRecorder: TraceRecorder | undefined): void;
5
+ export declare function attachResolverVendorPollObserver(traceRecorder: TraceRecorder, observer: () => void): TraceRecorder;
6
+ export declare const RESOLVER_VENDOR_CAPABILITIES: {
7
+ readonly browser: readonly ["aws_waf", "cloudflare_interstitial"];
8
+ readonly "2captcha": readonly ["turnstile", "recaptcha_v2", "recaptcha_v3", "hcaptcha", "aws_waf"];
9
+ readonly capsolver: readonly ["turnstile", "recaptcha_v2", "recaptcha_v3", "hcaptcha", "cloudflare_interstitial", "aws_waf"];
10
+ readonly capmonster: readonly ["turnstile", "recaptcha_v2", "recaptcha_v3", "hcaptcha"];
11
+ readonly hypersolutions: readonly ["akamai_sbsd"];
12
+ readonly custom: readonly ["turnstile", "recaptcha_v2", "recaptcha_v3", "hcaptcha", "cloudflare_interstitial", "aws_waf", "akamai_sec_cpt", "akamai_sensor", "akamai_sbsd"];
13
+ };
14
+ /**
15
+ * SDK-owned fallback policy for hosted resolver vendors. Capability support is
16
+ * applied separately, so each provider receives only vendors that support one
17
+ * or more of its declared challenge kinds.
18
+ */
19
+ export declare const DEFAULT_RESOLVER_VENDOR_PREFERENCE: readonly ["capsolver", "2captcha", "hypersolutions"];
20
+ export declare function resolverVendorSupports(vendor: ProviderResolverVendor, kind: ProviderChallengeKind): boolean;
21
+ /** Resolves an explicit provider override or the SDK-owned default vendor chain. */
22
+ export declare function resolveProviderResolverVendors(config: ProviderResolverConfig): readonly ProviderResolverVendor[];
23
+ export interface ResolverIdentity {
24
+ readonly proxyUrl: string;
25
+ readonly userAgent: string;
26
+ }
27
+ export interface ResolverIssuingIdentity {
28
+ /** Absent when the adapter genuinely solved without a proxy. */
29
+ readonly proxyUrl?: string;
30
+ readonly userAgent: string;
31
+ }
32
+ export interface ResolverVendorTransport {
33
+ /**
34
+ * Exact stable upstream headers owned by the proxy/profile-bound transport.
35
+ * This does not include dynamic Cookie headers; the transport injects those from its jar.
36
+ * Adapter requests do not receive these headers implicitly and must forward
37
+ * them when their measured protocol requires session-header continuity.
38
+ */
39
+ readonly sessionHeaders?: Readonly<Record<string, string>>;
40
+ /**
41
+ * Read a cookie from the transport's bound jar for the supplied URL. Responses
42
+ * returned by `fetch` MUST already have been applied to that jar before this
43
+ * method is called. Profile-bound adapters fail closed when this seam is absent.
44
+ */
45
+ readonly getCookie?: (name: string, url: string) => string | undefined;
46
+ /** Implementations MUST NOT follow redirects and must return the initial response. */
47
+ fetch(url: string, init: {
48
+ method: "GET" | "POST";
49
+ headers?: Readonly<Record<string, string>>;
50
+ body?: string;
51
+ signal: AbortSignal;
52
+ /** Implementations MUST honor manual redirect handling when the SDK guard sets it. */
53
+ redirect?: "manual";
54
+ /** Maximum UTF-8 response body size; implementations must stop reading at this bound. */
55
+ maxBodyBytes?: number;
56
+ }): Promise<{
57
+ readonly status: number;
58
+ readonly headers: Readonly<Record<string, string>>;
59
+ readonly body: string;
60
+ /** Cookies observed on the response, including cache-relevant attributes. */
61
+ readonly cookies: readonly {
62
+ readonly name: string;
63
+ readonly value: string;
64
+ /** Epoch seconds. A session cookie must be undefined, never CDP's -1 sentinel. */
65
+ readonly expires?: number;
66
+ readonly httpOnly: boolean;
67
+ readonly secure: boolean;
68
+ readonly domain?: string;
69
+ readonly path?: string;
70
+ readonly sameSite?: string;
71
+ }[];
72
+ }>;
73
+ }
74
+ /** Metering context the resolver chain hands each vendor adapter for its paid calls. */
75
+ export type ResolverPaidUsageContext = {
76
+ /** 1-based position of the vendor in the provider's declared resolver chain. */
77
+ readonly vendorIndex: number;
78
+ /** SHA-256 scope digest; never the raw affinity, proxy URL, cookie, or IP. */
79
+ readonly resolverIdentityScope?: string;
80
+ };
81
+ export interface ResolverVendorAdapter {
82
+ readonly id: ProviderResolverVendor;
83
+ readonly requiresTransport?: boolean | ((kind: ProviderChallengeKind) => boolean);
84
+ /**
85
+ * Exact SDK-owned service hosts this adapter may reach through its bound transport,
86
+ * in addition to the provider's `allowedHosts`. Every host must appear in the
87
+ * SDK-owned `RESOLVER_VENDOR_TRANSPORT_HOSTS` entry for `id`; the chain rejects any
88
+ * other declaration with `RESOLVER_VENDOR_HOST_NOT_ALLOWED`, whoever supplied the
89
+ * adapter. The transport handed to `solve` is revoked once `solve` settles.
90
+ */
91
+ readonly transportAllowedHosts?: readonly string[];
92
+ supports(kind: ProviderChallengeKind): boolean;
93
+ /** Identity the adapter actually used, reported after a successful solve. */
94
+ getIssuingIdentity?(solution: ChallengeSolution, requestedIdentity: ResolverIdentity | undefined, challenge: ProviderChallenge): ResolverIssuingIdentity | undefined;
95
+ solve(challenge: ProviderChallenge, identity: ResolverIdentity | undefined, signal: AbortSignal, traceRecorder?: TraceRecorder, transport?: ResolverVendorTransport, usage?: ResolverPaidUsageContext): Promise<ChallengeSolution>;
96
+ }
97
+ export type ResolverVendorUnavailableReason = "missing_credentials" | "missing_proxy_identity" | "missing_client_profile" | "missing_challenge_input" | "missing_transport" | "allocation_exhausted" | "transport_failure" | "timeout" | "not_implemented";
98
+ export type ResolverChallengeVerdictReason = "human_puzzle" | "solve_failed";
99
+ type ResolverErrorOptions = {
100
+ /** Raw cause; adapters must not place bodies, cookies, headers, credentials, or proxy URLs here. */
101
+ readonly cause?: unknown;
102
+ /** Names of challenge fields required by this adapter but absent from this call's input. */
103
+ readonly missingFields?: readonly string[];
104
+ /** Upstream hostname only; never a URL. */
105
+ readonly upstreamHost?: string;
106
+ /** Adapter-defined sensor-loop phase, such as fetch_script or post_sensor. */
107
+ readonly phase?: string;
108
+ /** One-based sensor-loop round when known. */
109
+ readonly round?: number;
110
+ };
111
+ export declare class ResolverVendorUnavailableError extends Error {
112
+ readonly vendor: ProviderResolverVendor;
113
+ readonly reason: ResolverVendorUnavailableReason;
114
+ readonly missingFields?: readonly string[];
115
+ readonly upstreamHost?: string;
116
+ readonly phase?: string;
117
+ readonly round?: number;
118
+ constructor(vendor: ProviderResolverVendor, reason: ResolverVendorUnavailableReason, options?: ResolverErrorOptions);
119
+ }
120
+ export declare class ResolverChallengeVerdictError extends Error {
121
+ readonly vendor: ProviderResolverVendor;
122
+ readonly reason: ResolverChallengeVerdictReason;
123
+ constructor(vendor: ProviderResolverVendor, reason: ResolverChallengeVerdictReason, options?: ResolverErrorOptions);
124
+ }
125
+ export {};
@@ -0,0 +1,106 @@
1
+ const RESOLVER_VENDOR_POLL_OBSERVER = Symbol.for("@apifuse/provider-sdk/runtime/resolver-vendor-poll-observer");
2
+ /** Internal chain-runner hook; vendor adapters never receive the telemetry sink itself. */
3
+ export function recordResolverVendorPoll(traceRecorder) {
4
+ traceRecorder?.[RESOLVER_VENDOR_POLL_OBSERVER]?.();
5
+ }
6
+ export function attachResolverVendorPollObserver(traceRecorder, observer) {
7
+ Object.defineProperty(traceRecorder, RESOLVER_VENDOR_POLL_OBSERVER, { value: observer });
8
+ return traceRecorder;
9
+ }
10
+ export const RESOLVER_VENDOR_CAPABILITIES = {
11
+ browser: ["aws_waf", "cloudflare_interstitial"],
12
+ // Every kind listed per vendor is implemented by that vendor's adapter; the
13
+ // per-adapter "agrees with every declared capability" tests iterate this
14
+ // table, so adding a kind here without an implementation fails the suite.
15
+ // 2captcha omits `cloudflare_interstitial` and every Akamai kind: its API
16
+ // offers no measured task type for them, so declaring them
17
+ // would route challenges to a vendor that can only refuse.
18
+ "2captcha": ["turnstile", "recaptcha_v2", "recaptcha_v3", "hcaptcha", "aws_waf"],
19
+ capsolver: [
20
+ "turnstile",
21
+ "recaptcha_v2",
22
+ "recaptcha_v3",
23
+ "hcaptcha",
24
+ "cloudflare_interstitial",
25
+ "aws_waf",
26
+ ],
27
+ capmonster: ["turnstile", "recaptcha_v2", "recaptcha_v3", "hcaptcha"],
28
+ // Hyper's /sbsd envelope is measured. Its sensor endpoint is deliberately
29
+ // omitted until that separate protocol is implemented and verified.
30
+ hypersolutions: ["akamai_sbsd"],
31
+ custom: [
32
+ "turnstile",
33
+ "recaptcha_v2",
34
+ "recaptcha_v3",
35
+ "hcaptcha",
36
+ "cloudflare_interstitial",
37
+ "aws_waf",
38
+ "akamai_sec_cpt",
39
+ "akamai_sensor",
40
+ "akamai_sbsd",
41
+ ],
42
+ };
43
+ /**
44
+ * SDK-owned fallback policy for hosted resolver vendors. Capability support is
45
+ * applied separately, so each provider receives only vendors that support one
46
+ * or more of its declared challenge kinds.
47
+ */
48
+ export const DEFAULT_RESOLVER_VENDOR_PREFERENCE = [
49
+ "capsolver",
50
+ "2captcha",
51
+ "hypersolutions",
52
+ ];
53
+ export function resolverVendorSupports(vendor, kind) {
54
+ return RESOLVER_VENDOR_CAPABILITIES[vendor].includes(kind);
55
+ }
56
+ /** Resolves an explicit provider override or the SDK-owned default vendor chain. */
57
+ export function resolveProviderResolverVendors(config) {
58
+ if (config.vendors !== undefined)
59
+ return config.vendors;
60
+ return DEFAULT_RESOLVER_VENDOR_PREFERENCE.filter((vendor) => config.kinds.some((kind) => resolverVendorSupports(vendor, kind)));
61
+ }
62
+ export class ResolverVendorUnavailableError extends Error {
63
+ vendor;
64
+ reason;
65
+ missingFields;
66
+ upstreamHost;
67
+ phase;
68
+ round;
69
+ constructor(vendor, reason, options = {}) {
70
+ const missingFields = reason === "missing_challenge_input"
71
+ ? options.missingFields?.filter((field) => /^[A-Za-z][A-Za-z0-9_]*$/u.test(field))
72
+ : undefined;
73
+ super(reason === "missing_challenge_input" &&
74
+ missingFields !== undefined &&
75
+ missingFields.length > 0
76
+ ? `Resolver vendor ${vendor} cannot use incomplete challenge input; missing fields: ${missingFields.join(", ")}`
77
+ : `Resolver vendor ${vendor} is unavailable: ${reason}`);
78
+ this.vendor = vendor;
79
+ this.reason = reason;
80
+ this.name = "ResolverVendorUnavailableError";
81
+ if (missingFields !== undefined && missingFields.length > 0) {
82
+ this.missingFields = Object.freeze([...missingFields]);
83
+ }
84
+ if (options.cause !== undefined) {
85
+ this.cause = options.cause;
86
+ }
87
+ this.upstreamHost = options.upstreamHost;
88
+ this.phase = options.phase;
89
+ this.round = options.round;
90
+ }
91
+ }
92
+ export class ResolverChallengeVerdictError extends Error {
93
+ vendor;
94
+ reason;
95
+ constructor(vendor, reason, options = {}) {
96
+ super(reason === "solve_failed"
97
+ ? `Resolver vendor ${vendor} attempted the challenge but did not solve it`
98
+ : `Resolver vendor ${vendor} returned a challenge verdict: ${reason}`);
99
+ this.vendor = vendor;
100
+ this.reason = reason;
101
+ this.name = "ResolverChallengeVerdictError";
102
+ if (options.cause !== undefined) {
103
+ this.cause = options.cause;
104
+ }
105
+ }
106
+ }