@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
@@ -1,37 +1,145 @@
1
1
  ---
2
2
  name: health-checks-and-fail-closed
3
- description: Writing health checks that can actually fail, and fail-closed guards at envelope and row level. Load before writing healthCheck blocks or error handling.
3
+ description: Writing health checks the platform monitor actually executes, and fail-closed guards at envelope and row level. Load before writing healthCheck blocks or error handling.
4
4
  ---
5
5
 
6
6
  # Health checks and fail-closed guards
7
7
 
8
- ## Health checks that can actually fail
9
- `Array.isArray(data.items)` alone can never fail. Every list operation's
10
- health check must be able to detect the zero-rows regression.
8
+ ## Only `scenario` is monitored in production
11
9
 
12
- Assertion contract (per SDK `HealthCheckCase`): THROW to fail the case
13
- (recorded as `down`); return `{ status: "degraded", label }` to flag without
14
- failing; return nothing for `ok`. There is no `"down"` return value.
10
+ A `healthCheck` case takes one of two mutually exclusive shapes, and they do
11
+ not run in the same place:
12
+
13
+ | field | executed by | when |
14
+ |---|---|---|
15
+ | `scenario` | the platform health monitor | every suite interval, in production |
16
+ | `assertions` | the provider runtime's own self-test | only when that endpoint is called |
17
+
18
+ The monitor runs a case's SERIALIZED scenario and nothing else: a closure
19
+ cannot cross the registry's serialization boundary. A case that carries only
20
+ `assertions` is still published as a probe, but its outcome is permanently
21
+ `unknown` / `monitoring_unavailable` — the operation reads as monitored on the
22
+ status page while nothing is ever checked. `apifuse check` warns about this
23
+ (`health-check-assertions-not-monitored`).
24
+
25
+ Anything that must be caught in production belongs in `scenario`. Keep
26
+ `assertions` for a local self-test, or drop it.
27
+
28
+ ## A scenario that can actually fail
29
+
30
+ `Array.isArray(data.items)` alone can never fail. Every list operation's probe
31
+ must be able to detect the zero-rows regression AND a mapper regression that
32
+ empties fields on a present row.
33
+
34
+ Step kinds: `operation` invokes, `assert` FAILS the probe (recorded `down`),
35
+ `guard` DEGRADES without failing it.
36
+
37
+ ```ts
38
+ // health-scenarios.ts
39
+ import { type AssertionExpression, defineHealthScenario } from "@apifuse/provider-sdk/provider";
40
+
41
+ export const PROBE_INPUT = { district: "<a guaranteed-dense, stable id>" } as const;
42
+
43
+ const response = (path: readonly (string | number)[]) => ({
44
+ ref: { namespace: "steps" as const, binding: "response", path: [...path] },
45
+ });
46
+
47
+ const evidence: AssertionExpression = {
48
+ kind: "all",
49
+ clauses: [
50
+ { kind: "predicate", operator: "status_2xx", actual: response(["status_code"]) },
51
+ // Dense query MUST return rows; zero rows = upstream contract drift.
52
+ { kind: "predicate", operator: "array_length_gte", actual: response(["data", "items"]), expected: 1 },
53
+ // A semantic field on a real row, so an emptying mapper regression fails too.
54
+ { kind: "predicate", operator: "non_empty", actual: response(["data", "items", 0, "name"]) },
55
+ ],
56
+ };
57
+
58
+ export const listItemsScenario = defineHealthScenario({
59
+ scenarioVersion: 2,
60
+ id: "list-items.dense-district",
61
+ display: {
62
+ titleKey: "health.operations.list-items.dense-district.title",
63
+ descriptionKey: "health.operations.list-items.dense-district.description",
64
+ },
65
+ schedule: { kind: "interval", intervalMs: 60 * 60_000, jitterMs: 0 },
66
+ timeoutMs: 15_000,
67
+ coversOperations: ["list-items"],
68
+ credentialRefs: [],
69
+ steps: [
70
+ { id: "read", result: "response", kind: "operation", operationId: "list-items", inputTemplate: { ...PROBE_INPUT } },
71
+ { id: "verify", result: "verified", kind: "assert", coversOperations: ["list-items"], expression: evidence },
72
+ ],
73
+ });
74
+ ```
15
75
 
16
76
  ```ts
17
- assertions: ({ status, data }) => {
18
- if (status !== 200) {
19
- throw new Error(`<op> request failed with status ${status}`);
20
- }
21
- if (!Array.isArray(data.items)) {
22
- throw new Error("<op> missing items array");
23
- }
24
- // Dense query MUST return rows; zero rows = upstream contract drift
25
- if (data.items.length === 0) {
26
- return { status: "degraded", label: "<op> dense query returned 0 rows" };
27
- }
77
+ // operations/list-items.ts
78
+ healthCheck: {
79
+ interval: "1h",
80
+ timeoutMs: 15_000,
81
+ cases: [{ name: "dense-district", input: { ...PROBE_INPUT }, scenario: listItemsScenario }],
28
82
  }
29
83
  ```
30
84
 
31
- - Choose health-check inputs that are guaranteed-dense (major city district,
32
- a stable well-known entity id). Verify the id still exists when picking it.
33
- - Also assert one semantic field on the first row (e.g. `items[0].name` is a
34
- non-empty string) so a mapper regression that empties fields degrades too.
85
+ - Choose probe inputs that are guaranteed-dense (major city district, a stable
86
+ well-known entity id). Verify the id still exists when picking it.
87
+ - `scenario.coversOperations` may only name the operation that owns the case.
88
+
89
+ ## Stale-if-error serves must be guarded, or an outage reads green
90
+
91
+ If the operation reads its upstream through `ctx.cache.getOrSet(..., {
92
+ staleIfErrorMs })`, an upstream outage is answered with HTTP 200 and a
93
+ well-formed, fully schema-valid body for the whole stale window. Every clause
94
+ over `status_code` and `data` still passes, so the probe rolls up `ok` while
95
+ the upstream is down, and only flips to `down` after the window expires — the
96
+ first minutes of every outage are reported as healthy.
97
+
98
+ `served_stale_cache` on the operation step result is the only operand that
99
+ separates a stale serve from a live read. It is always present, so the
100
+ reference resolves to `false` rather than raising `reference_unresolvable`.
101
+ Add ONE guard step per stale-if-error probe:
102
+
103
+ ```ts
104
+ {
105
+ id: "guard-list-items-freshness",
106
+ result: "freshness-guarded",
107
+ kind: "guard",
108
+ condition: {
109
+ kind: "predicate",
110
+ operator: "not_equals",
111
+ actual: { ref: { namespace: "steps" as const, binding: "response", path: ["served_stale_cache"] } },
112
+ expected: true,
113
+ },
114
+ onFail: {
115
+ attribute: [
116
+ {
117
+ operationId: "list-items",
118
+ status: "degraded",
119
+ reasonCode: "served_stale_cache",
120
+ reasonKey: "health.operations.list-items.dense-district.servedStaleCache",
121
+ },
122
+ ],
123
+ stop: "scenario",
124
+ },
125
+ }
126
+ ```
127
+
128
+ - `degraded`, not `down`: the cache policy is behaving as promised and callers
129
+ are still served; it is the upstream that is unavailable, and that has to be
130
+ visible instead of green.
131
+ - `served_stale_cache`, not `expected_absence`: the platform publishes a
132
+ stale serve as `degraded` (an upstream fault that opens incidents), while
133
+ `expected_absence` is published as a non-incident status — neither ok nor
134
+ degraded, excluded from uptime — for an absence the provider declares in
135
+ advance (no alert today, a closed shelf, a feed outside its hours). The
136
+ tenant-facing wording lives in the localized `reasonKey`.
137
+ - Place the freshness guard BEFORE any row or emptiness guard. A stale serve
138
+ that happens to be empty would otherwise be attributed to the emptiness
139
+ reason, which is a confident answer to the wrong question.
140
+ - Do not change the handler for this. The envelope's `meta.stale` is written
141
+ by the serve layer, so `return result.value` discarding `result.meta` does
142
+ not suppress the signal.
35
143
 
36
144
  ## Fail-closed: envelope level
37
145
  - Upstream error headers/codes → structured `ProviderError` with a stable
@@ -51,6 +159,14 @@ array is non-empty, but every row normalizes to nothing.
51
159
  - Regression-test both layers separately: a bad envelope AND a good envelope
52
160
  with unmappable rows.
53
161
 
162
+ ## Self-test assertions (optional, not monitored)
163
+ A case without a `scenario` may carry an `assertions` lambda, executed only by
164
+ the provider runtime's own self-test. THROW to fail the case (recorded
165
+ `down`); return `{ status: "degraded", label }` to flag without failing;
166
+ return nothing for `ok`. There is no `"down"` return value. It MUST NOT touch
167
+ the scheduler, recorder, or any runtime type. Never use it as the only check
168
+ on an operation you need monitored.
169
+
54
170
  ## Error message hygiene
55
171
  `ProviderError.message` reaches the tenant verbatim. Never interpolate
56
172
  upstream free text that may contain personal data (names, phone numbers,
@@ -58,8 +174,10 @@ addresses); allowlist known code tokens and keep raw bodies in server-side
58
174
  details/logs only.
59
175
 
60
176
  ## Checklist
61
- - [ ] Every list op health check flags 0 rows on a dense query
177
+ - [ ] Every monitored operation's case carries `scenario` (not only `assertions`)
178
+ - [ ] Every list op probe fails on 0 rows for a dense query
62
179
  - [ ] One semantic field asserted on a real row
180
+ - [ ] Every `staleIfErrorMs` read has a `served_stale_cache` guard, placed first
63
181
  - [ ] Swallowed-error test exists (non-ok mock → handler rejects)
64
182
  - [ ] Non-empty upstream → zero normalized rows throws
65
183
  - [ ] No upstream free text in customer-facing error messages
@@ -1,6 +1,6 @@
1
1
  FROM oven/bun:1.2-alpine
2
2
  WORKDIR /provider
3
- COPY package.json bun.lockb* ./
3
+ COPY package.json bun.lock ./
4
4
  RUN bun install --frozen-lockfile
5
5
  COPY . .
6
6
  EXPOSE 3000
@@ -97,9 +97,21 @@ The `POST /v1/{operation}` body is a request envelope:
97
97
  - `requestId` is required and can be any unique local debugging string.
98
98
  - `input` contains the operation input shape.
99
99
  - `headers` is optional.
100
- - `connection` is optional; omit it for no-auth/public operations. For
101
- credential debugging, pass `{ "id", "mode", "secrets", "metadata",
102
- "externalRef" }` with local-only secret values.
100
+ - `connectionId` is optional connection identity only and does not include
101
+ credentials. The gateway sends it for `optional` connection mode, and only
102
+ when the caller supplied a connection that passed authorization. It is
103
+ exposed as `ctx.request.connectionId`.
104
+ - `connection` is optional credential-bearing connection data. The gateway
105
+ sends it for `required` connection mode; omit it for no-auth/public (`none`
106
+ mode) operations. For local debugging, pass
107
+ `{ "id", "mode", "secrets", "metadata", "externalRef" }` with local-only
108
+ secret values.
109
+
110
+ The gateway sends only `connection` for `required` mode, only `connectionId`
111
+ for `optional` mode (and nothing when the caller passed no connection), and
112
+ neither field for `none` mode. If a malformed or manually constructed envelope
113
+ contains both, a non-empty nested `connection.id` takes precedence over the
114
+ top-level `connectionId`; an empty string is treated as absent.
103
115
 
104
116
  Structured errors return an `error` object with `code`, `message`,
105
117
  `requestId`, and optional `details`; validation failures include field paths in
@@ -109,22 +121,24 @@ Structured errors return an `error` object with `code`, `message`,
109
121
 
110
122
  - `invalid_request`: include `requestId` and `input`; omit `connection` for
111
123
  public/no-auth operations and never send `connection: null`.
112
- - Credentials: declare `credential.keys`, pass local-only values through
113
- `connection.secrets`, and read them with `ctx.credential`.
124
+ - Credentials: declare `credential.keys` unless `auth.mode` is `platform-managed`;
125
+ that mode implies an unfiltered credential capability and forbids key declarations.
126
+ Pass local-only values through `connection.secrets` and read them with
127
+ `ctx.credential`.
114
128
  - Auth flow: call `/auth/start`, then `/auth/continue` with the same `flowId`;
115
129
  carry returned `contextPatch` values into the next request's `context`.
116
- - Stealth/browser runtime: keep access-sensitive operations on `ctx.stealth.fetch()` with an
117
- SDK stealth `profile`; the TypeScript stealth runtime uses `impit` internally.
118
- `ctx.stealth` supports Chrome/Firefox-style profiles. For TypeScript browser
119
- Providers or Safari-specific behavior use `browser.engine: "playwright-stealth"`
120
- (`nodriver` is Python-runtime only), then install local Chromium with
130
+ - Stealth/browser runtime: keep access-sensitive operations on `ctx.stealth.fetch()` with
131
+ structured SDK `stealth: { browser, os }` selection; the TypeScript stealth runtime uses
132
+ `wreq-js` internally and supports Chrome, Firefox, and Safari. Use `ctx.browser` only when
133
+ the provider needs browser execution; TypeScript browser Providers use
134
+ `browser.engine: "playwright-stealth"` (`nodriver` is Python-runtime only). Install local Chromium with
121
135
  `bunx playwright install chromium` or set `APIFUSE__CDP_POOL__URL`.
122
136
 
123
137
  ## Next steps
124
138
 
125
139
  1. Replace the sample `ping` operation with real upstream logic.
126
- 2. Once the real operation declares `upstream.baseUrl` and uses `ctx.http` or
127
- `ctx.stealth`, record a fixture with:
140
+ 2. Once the real operation calls the upstream through `ctx.http` or `ctx.stealth`
141
+ (absolute URLs, or relative ones under its `upstream.baseUrl`), record a fixture with:
128
142
  `bun run record -- --operation <operation> --params '<json-input>'`.
129
143
  3. Replace the starter `healthCheckUnsupported` with a real `healthCheck` for read-only upstream operations when safe.
130
144
  4. Extend tests and operation metadata until the provider is bounty-ready.
@@ -144,8 +158,14 @@ Every operation must declare exactly one of:
144
158
  The generated `ping` operation uses `healthCheckUnsupported` only because it is
145
159
  a local scaffold check, not a real upstream API probe.
146
160
 
147
- `healthCheck.cases[].assertions` receives `{ data, status, durationMs, meta }`.
148
- `data` is the parsed operation output. Use this shape in real operations:
161
+ A case carries either `scenario` or `assertions`, and only `scenario` is
162
+ executed in production: the platform health monitor runs a case's serialized
163
+ scenario and nothing else, because a closure cannot cross the registry's
164
+ serialization boundary. A case with only `assertions` still publishes a probe,
165
+ but its outcome is permanently `unknown` / `monitoring_unavailable` — the
166
+ operation reads as monitored while nothing is checked, and `apifuse check`
167
+ warns about it (`health-check-assertions-not-monitored`). Use this shape in
168
+ real operations:
149
169
 
150
170
  ```ts
151
171
  healthCheck: {
@@ -153,11 +173,13 @@ healthCheck: {
153
173
  cases: [{
154
174
  name: "lookup baseline",
155
175
  input: { q: "btc" },
156
- assertions: ({ data, status, durationMs }) => {
157
- if (status !== 200 || data.results.length === 0 || durationMs > 3000) {
158
- return { status: "degraded", label: "lookup baseline changed" };
159
- }
160
- },
176
+ scenario: lookupBaselineScenario, // defineHealthScenario({ ... })
161
177
  }],
162
178
  }
163
179
  ```
180
+
181
+ If the operation reads through `ctx.cache.getOrSet(..., { staleIfErrorMs })`,
182
+ add a guard step on the operation step result's `served_stale_cache` as well —
183
+ otherwise an upstream outage is answered with a schema-valid 200 and the probe
184
+ reports `ok` for the whole stale window. See
185
+ `.agents/skills/health-checks-and-fail-closed/SKILL.md` for both shapes.
@@ -1,9 +1,9 @@
1
- import { defineProvider } from "@apifuse/provider-sdk/provider";
1
+ import { defineProvider, type ProviderContextOf } from "@apifuse/provider-sdk/provider";
2
2
 
3
3
  import { providerMeta } from "./meta";
4
4
  import { operations } from "./operations";
5
5
 
6
- export default defineProvider({
6
+ const buildProvider = defineProvider({
7
7
  id: "{{PROVIDER_ID}}",
8
8
  version: "1.0.0",
9
9
  runtime: "{{RUNTIME}}"{{BROWSER_BLOCK}},
@@ -11,5 +11,8 @@ export default defineProvider({
11
11
  reviewed: "community",
12
12
  {{SECRETS_BLOCK}}{{CREDENTIAL_BLOCK}}auth: {{AUTH_BLOCK}},
13
13
  meta: providerMeta,
14
- operations: operations,
15
14
  });
15
+
16
+ export type ProviderContext = ProviderContextOf<typeof buildProvider>;
17
+
18
+ export default buildProvider({ operations });
@@ -1,8 +1,11 @@
1
1
  import { defineOperation } from "@apifuse/provider-sdk/provider";
2
+ import type { ProviderContext } from "../index";
2
3
 
3
4
  import { pingInputSchema, pingOutputSchema } from "../schemas/ping";
4
5
 
5
- export const pingOperation = defineOperation({
6
+ export const pingOperation = defineOperation<ProviderContext>()({
7
+ connectionMode: "none",
8
+ riskClass: "read",
6
9
  descriptionKey: "operations.ping.description",
7
10
  input: pingInputSchema,
8
11
  output: pingOutputSchema,
@@ -0,0 +1,6 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "providerId": "{{PROVIDER_ID}}",
4
+ "owner": "bounty",
5
+ "lifecycle": "draft"
6
+ }
@@ -1,5 +1,9 @@
1
- import { Redis } from "ioredis";
1
+ import type { Redis } from "ioredis";
2
2
  import type { ProviderProxyPolicy, TraceConfig } from "../types.js";
3
+ import { type ProxyProtocol } from "../runtime/proxy-nodemaven.js";
4
+ export type { ProxyProtocol } from "../runtime/proxy-nodemaven.js";
5
+ /** Proxy vendors with SDK-managed resolution. */
6
+ export type ProxyVendorName = "smartproxy" | "nodemaven";
3
7
  export declare const SMARTPROXY_APP_KEY_ENV = "APIFUSE__PROXY__SMARTPROXY_APP_KEY";
4
8
  export declare const SMARTPROXY_MAX_LIFETIME_MINUTES = 2000;
5
9
  export declare const DEFAULT_SMARTPROXY_POOL_SIZE = 20;
@@ -10,13 +14,6 @@ export declare const DEFAULT_PROXY_LIFETIME_ENV = "APIFUSE__PROXY__DEFAULT_LIFET
10
14
  export declare const PROVIDER_CACHE_REDIS_URL_ENV = "APIFUSE__PROVIDER__CACHE_REDIS_URL";
11
15
  export declare const PROVIDER_STATE_REDIS_URL_ENV = "APIFUSE__PROVIDER__STATE_REDIS_URL";
12
16
  export declare const REDIS_URL_ENV = "APIFUSE__REDIS__URL";
13
- export type ProxyOptions = {
14
- url: string;
15
- };
16
- export type ProxyConfig = Partial<ProxyOptions> & {
17
- provider?: string;
18
- apiKey?: string;
19
- };
20
17
  export type BrowserConfig = {
21
18
  executablePath?: string;
22
19
  headless?: boolean;
@@ -26,7 +23,6 @@ export type SessionConfig = {
26
23
  path?: string;
27
24
  };
28
25
  export type ApiFuseConfig = {
29
- proxy?: ProxyConfig;
30
26
  browser?: BrowserConfig;
31
27
  session?: SessionConfig;
32
28
  trace?: TraceConfig;
@@ -37,17 +33,43 @@ export type ProxyResolutionOptions = {
37
33
  upstream?: {
38
34
  proxy?: boolean | ProviderProxyPolicy;
39
35
  };
40
- apifuseConfig?: Pick<ApiFuseConfig, "proxy">;
41
36
  proxyPolicy?: ProviderProxyPolicy;
42
37
  affinityKey?: string;
43
38
  /** Zero-based proxy-pool attempt index used by SDK transports for failover. */
44
39
  proxyAttempt?: number;
40
+ /**
41
+ * Tunnelling protocols the calling transport can use. When a resolved
42
+ * protocol is not in this set the resolver fails with
43
+ * `PROXY_PROTOCOL_UNSUPPORTED` instead of silently downgrading. Unset means
44
+ * permissive (both protocols allowed).
45
+ */
46
+ transportProtocols?: readonly ProxyProtocol[];
47
+ /**
48
+ * Explicit protocol override. Internal — for the verification harness and
49
+ * tests, or an advanced caller. Normal callers omit it and each vendor uses
50
+ * its own benchmarked default protocol (see VENDOR_DEFAULT_PROTOCOL). Not an
51
+ * env var and not a provider-policy field.
52
+ */
53
+ protocol?: ProxyProtocol;
54
+ /**
55
+ * Gateway pool "refresh" generation. Bumped by transports on pool refresh to
56
+ * derive a fresh gateway session set (ignored by allocation-style vendors,
57
+ * whose refresh is driven by cache invalidation).
58
+ */
59
+ proxyRefreshEpoch?: number;
45
60
  telemetry?: ProxyTelemetrySink;
61
+ /** Engine-owned credential snapshot. Provider code must never populate this field. */
62
+ engineCredentials?: Readonly<Record<string, string>>;
46
63
  };
47
64
  export type ProxyCacheStatus = "memory_hit" | "redis_hit" | "allocator" | "soft_stale_refresh" | "lock_wait" | "redis_error" | "redis_corrupt" | "disabled";
48
65
  export type SmartproxyAllocatorBodyClass = "network_error" | "http_error" | "empty" | "json_without_proxies" | "text_without_proxies" | "usable_proxy_endpoints";
66
+ export type ProxyUserAgentSource = "declared" | "defaulted";
49
67
  export type ProxyResolutionTelemetryEvent = {
50
- provider: "smartproxy";
68
+ provider: ProxyVendorName;
69
+ /** Defaults to `"ok"` when omitted. */
70
+ outcome?: "ok" | "error";
71
+ userAgentSource?: ProxyUserAgentSource;
72
+ protocol?: ProxyProtocol;
51
73
  cacheStatus: ProxyCacheStatus;
52
74
  cacheHit: boolean;
53
75
  resolutionMs: number;
@@ -64,7 +86,7 @@ export type ProxyResolutionTelemetryEvent = {
64
86
  refreshes?: number;
65
87
  };
66
88
  export type ProxyAttemptTelemetryEvent = {
67
- provider: "smartproxy";
89
+ provider: ProxyVendorName;
68
90
  attempt: number;
69
91
  poolIndex?: number;
70
92
  proxyHash?: string;
@@ -73,35 +95,199 @@ export type ProxyAttemptTelemetryEvent = {
73
95
  status?: number;
74
96
  durationMs?: number;
75
97
  };
98
+ export type ProxyVendorFailoverTelemetryEvent = {
99
+ /** Vendor that failed or was skipped. */
100
+ vendor: ProxyVendorName;
101
+ /** Vendor tried next, or undefined when the chain is exhausted. */
102
+ nextVendor?: ProxyVendorName;
103
+ phase: "resolution" | "transport";
104
+ reason: "no_credentials" | "allocation_failed" | "pool_exhausted" | "protocol_unsupported";
105
+ attempt?: number;
106
+ };
76
107
  export type ProxyTelemetrySink = {
77
108
  recordProxyResolution(event: ProxyResolutionTelemetryEvent): void;
78
109
  recordProxyAttempt?(event: ProxyAttemptTelemetryEvent): void;
110
+ recordProxyVendorFailover?(event: ProxyVendorFailoverTelemetryEvent): void;
79
111
  };
112
+ export type ProxyResolutionSource = "explicit" | "env" | "config" | "smartproxy-allocator" | "nodemaven-gateway";
80
113
  export type ResolvedProxyConfig = {
81
114
  shouldWarn: boolean;
82
115
  url?: string;
83
- source?: "explicit" | "env" | "config" | "smartproxy-allocator";
116
+ /** SDK-native vendor that supplied the URL, when applicable. */
117
+ vendor?: ProxyVendorName;
118
+ source?: ProxyResolutionSource;
119
+ protocol?: ProxyProtocol;
84
120
  diagnostics?: Record<string, string | number | boolean>;
85
121
  };
122
+ export type ProxyResolutionErrorCode = "PROXY_REQUIRED" | "PROXY_ALLOCATION_FAILED" | "PROXY_PROTOCOL_UNSUPPORTED";
86
123
  export declare class ProxyResolutionError extends Error {
87
- readonly code: "PROXY_REQUIRED" | "PROXY_ALLOCATION_FAILED";
124
+ readonly code: ProxyResolutionErrorCode;
88
125
  readonly telemetry?: ProxyResolutionTelemetryEvent;
89
- constructor(code: "PROXY_REQUIRED" | "PROXY_ALLOCATION_FAILED", message: string, options?: {
126
+ readonly vendor?: ProxyVendorName;
127
+ readonly vendorChain?: ProxyVendorName[];
128
+ readonly protocol?: ProxyProtocol;
129
+ constructor(code: ProxyResolutionErrorCode, message: string, options?: {
90
130
  cause?: unknown;
91
131
  telemetry?: ProxyResolutionTelemetryEvent;
132
+ vendor?: ProxyVendorName;
133
+ vendorChain?: ProxyVendorName[];
134
+ protocol?: ProxyProtocol;
92
135
  });
93
136
  }
94
137
  type ProxyRedisClient = Pick<Redis, "connect" | "del" | "eval" | "get" | "on" | "pttl" | "set" | "status">;
138
+ /** Env names that can supply a provider store's Redis URL. */
139
+ export type ProviderRedisUrlEnvName = typeof PROVIDER_STATE_REDIS_URL_ENV | typeof PROVIDER_CACHE_REDIS_URL_ENV | typeof REDIS_URL_ENV;
140
+ /** Which env name supplied a store's Redis URL, alongside the URL itself. */
141
+ export type ProviderRedisUrlResolution = {
142
+ readonly url: string;
143
+ /** The env name that actually supplied `url`. */
144
+ readonly envName: ProviderRedisUrlEnvName;
145
+ /**
146
+ * True when `url` came from a shared fallback env rather than the store's
147
+ * own. A state store on `fallback: true` is sharing an instance that was
148
+ * provisioned for something else (apifuse#2144).
149
+ */
150
+ readonly fallback: boolean;
151
+ };
152
+ export declare function providerCacheRedisResolutionFromEnv(): ProviderRedisUrlResolution | undefined;
153
+ export declare function providerStateRedisResolutionFromEnv(): ProviderRedisUrlResolution | undefined;
95
154
  export declare function providerCacheRedisUrlFromEnv(): string | undefined;
96
155
  export declare function providerStateRedisUrlFromEnv(): string | undefined;
97
156
  /** @internal Test-only hook for exercising shared proxy-cache behavior. */
98
157
  export declare function __setProxyRedisForTests(redis: ProxyRedisClient | undefined): void;
99
158
  export declare function __setSmartproxyAllocatorDeadlineMsForTests(deadlineMs: number | undefined): void;
159
+ /** @internal Test-only hook for exercising the pool-cache capacity bound at a small size. */
160
+ export declare function __setSmartproxyPoolCacheMaxEntriesForTests(maxEntries: number | undefined): void;
161
+ /** @internal Test-only view of the in-memory Smartproxy cache sizes. */
162
+ export declare function __getSmartproxyCacheSizesForTests(): {
163
+ pools: number;
164
+ tombstones: number;
165
+ };
100
166
  export declare function resolveProxyConfig(options?: ProxyResolutionOptions): ResolvedProxyConfig;
101
167
  export declare function resolveProxyConfigAsync(options?: ProxyResolutionOptions): Promise<ResolvedProxyConfig>;
168
+ /**
169
+ * Resolve the proxy URL for a provider-owned consumer such as a CAPTCHA solver.
170
+ * Vendor allocation and failover remain owned by the SDK.
171
+ */
172
+ export declare function resolveProxy(options?: ProxyResolutionOptions): Promise<ResolvedProxyConfig>;
173
+ /**
174
+ * Each vendor's default egress protocol, chosen from live KR benchmarks. HTTP
175
+ * CONNECT wins for nodemaven (socks5 adds ~500ms through the gateway) and ties
176
+ * for smartproxy, and is the only protocol ctx.http (Bun native fetch) supports.
177
+ * Override per call via ProxyResolutionOptions.protocol (harness/tests).
178
+ */
179
+ export declare const VENDOR_DEFAULT_PROTOCOL: Readonly<Record<ProxyVendorName, ProxyProtocol>>;
180
+ /**
181
+ * Guard the No-MITM invariant: a resolved proxy URL must use a tunnelling scheme
182
+ * (http CONNECT or socks5) so the client TLS handshake reaches the origin
183
+ * end-to-end. Anything else would intercept TLS and break fingerprinting.
184
+ */
185
+ export declare function assertTunnelingScheme(url: string): void;
186
+ export type ProxyVendorResolutionContext = {
187
+ readonly protocol: ProxyProtocol;
188
+ readonly poolIndex: number;
189
+ readonly refreshEpoch: number;
190
+ /** Explicit vendor credentials. Omit only on the legacy ambient-env path. */
191
+ readonly credentials?: Readonly<Record<string, string>>;
192
+ /** Disable non-policy env defaults for deterministic injected adapters. */
193
+ readonly ambientDefaults?: boolean;
194
+ /** Disable env-discovered Redis sharing for deterministic injected adapters. */
195
+ readonly sharedCache?: boolean;
196
+ };
197
+ export declare function resolveWithVendor(vendor: ProxyVendorName, policy: ProviderProxyPolicy, options: ProxyResolutionOptions, context: ProxyVendorResolutionContext): Promise<ResolvedProxyConfig>;
198
+ /**
199
+ * Ordered list of SDK-native proxy vendors declared by the policy. `providers`
200
+ * takes precedence over the legacy singular `provider`; the platform default
201
+ * env is the final fallback. Non-registry names (decodo/custom) are dropped so
202
+ * an all-deprecated chain has no managed adapter.
203
+ */
204
+ export declare function resolveVendorChain(policy: ProviderProxyPolicy): ProxyVendorName[];
205
+ /**
206
+ * Total attempt span across a policy's vendor chain — the sum of each vendor's
207
+ * pool size. Transports use this so successive attempts rotate a vendor's pool
208
+ * and then fail over to the next vendor via the flat attempt index. With one
209
+ * vendor this equals that vendor's pool size (today's behaviour).
210
+ */
211
+ export declare function resolvePolicyProxyPoolSpan(policy: ProviderProxyPolicy): number;
212
+ /**
213
+ * Absolute upper bound on a chain's attempt span — the sum of each vendor's
214
+ * *maximum* pool size. Unlike `resolvePolicyProxyPoolSpan` (the configured
215
+ * span), this backstop is independent of `session.poolSize`, so it never
216
+ * truncates a legitimately large pool below the point where the flat attempt
217
+ * index would cross into the next vendor (e.g. a 50-slot NodeMaven pool).
218
+ */
219
+ export declare function maxPolicyProxyPoolSpan(policy: ProviderProxyPolicy): number;
220
+ /**
221
+ * Transport-retry attempt cap for a policy-managed request. A transport failure
222
+ * rotates the flat attempt index onto the *next* endpoint (and, once the index
223
+ * passes the primary vendor's pool span, the *next vendor*), so the cap must be
224
+ * the chain's full pool span for failover to reach the fallback vendor — the
225
+ * per-endpoint retry budget (default 3) never gets there.
226
+ *
227
+ * The span only widens beyond the caller's retry budget when ALL hold:
228
+ * - the request is policy-allocator managed (not a caller-supplied proxy URL);
229
+ * - the caller did NOT pin an explicit retry policy — `HttpRetryOptions.attempts`
230
+ * is the documented total-attempt ceiling and must be honoured verbatim;
231
+ * - the method is safe/idempotent — an unsafe request must never be duplicated
232
+ * across the pool even if some framework default would allow it;
233
+ * - the policy resolves a non-empty *registry* vendor chain (smartproxy /
234
+ * nodemaven). Deprecated vendors (custom / decodo) resolve no managed pool,
235
+ * so there is no possible endpoint crossover — they keep the retry budget.
236
+ *
237
+ * The widened cap is bounded by the chain's true maximum span (sum of each
238
+ * vendor's max pool size), so a large NodeMaven pool (≤50) stays reachable and
239
+ * a pathological chain can never spin unbounded.
240
+ */
241
+ /**
242
+ * True when a policy request is in *implicit chain-rotation* mode: successive
243
+ * transport attempts rotate the flat index across the concatenated vendor pool
244
+ * spans (and, past the primary vendor's span, into the fallback vendor). This is
245
+ * the ONLY mode in which the transport loop widens its attempt cap AND
246
+ * de-duplicates repeated endpoints — the two behaviours must share one predicate
247
+ * so they never diverge. It holds when ALL of the widening conditions hold:
248
+ * - the request is policy-allocator managed (not a caller-supplied proxy URL);
249
+ * - the caller did NOT pin an explicit retry policy — its `attempts` ceiling is
250
+ * the documented contract and must be honoured verbatim against whatever
251
+ * endpoint each attempt resolves (even a repeated one), so no de-duplication;
252
+ * - the method is safe/idempotent — an unsafe request is never duplicated;
253
+ * - the policy resolves a non-empty registry vendor chain (smartproxy /
254
+ * nodemaven). Deprecated vendors (custom / decodo) resolve no managed
255
+ * endpoint, so there is nothing to rotate or de-duplicate.
256
+ */
257
+ export declare function policyRotatesTransportVendorChain(input: {
258
+ policy: ProviderProxyPolicy | undefined;
259
+ usesPolicyAllocator: boolean;
260
+ explicitRetry: boolean;
261
+ method: string;
262
+ }): boolean;
263
+ export declare function resolvePolicyTransportAttemptCap(input: {
264
+ policy: ProviderProxyPolicy | undefined;
265
+ usesPolicyAllocator: boolean;
266
+ retryAttempts: number;
267
+ explicitRetry: boolean;
268
+ method: string;
269
+ }): number;
270
+ /**
271
+ * A registry vendor chain (smartproxy/nodemaven) resolves a potentially
272
+ * *different* endpoint per flat attempt index, so a transport retry should
273
+ * advance across endpoints and de-duplicate once the chain stops yielding new
274
+ * ones. Deprecated custom/decodo policies have an empty registry chain and no
275
+ * managed endpoint, so the transport loop has nothing to rotate or de-duplicate.
276
+ */
277
+ export declare function policyResolvesRegistryVendorChain(policy: ProviderProxyPolicy | undefined): boolean;
278
+ /** Map a resolved proxy source label to the vendor that served it. */
279
+ export declare function vendorFromResolvedSource(source: ResolvedProxyConfig["source"]): ProxyVendorName | undefined;
280
+ /**
281
+ * Map a flat attempt index into (vendorIndex, poolIndex) by concatenating each
282
+ * vendor's pool space in chain order. With a single vendor this reduces to
283
+ * `attempt % poolSize`, preserving today's behaviour exactly.
284
+ */
285
+ export declare function mapFlatAttempt(flat: number, sizes: readonly number[]): {
286
+ vendorIndex: number;
287
+ poolIndex: number;
288
+ };
102
289
  export declare function clearProxyResolutionCache(): void;
103
290
  export declare function invalidateProxyResolutionCache(options?: ProxyResolutionOptions): boolean;
104
291
  export declare function invalidateProxyResolutionCacheAsync(options?: ProxyResolutionOptions): Promise<boolean>;
105
292
  export declare function defineConfig(config: ApiFuseConfig): ApiFuseConfig;
106
293
  export declare function loadApiFuseConfig(dir?: string): Promise<ApiFuseConfig>;
107
- export {};