@apifuse/provider-sdk 2.2.0-beta.2 → 2.2.0-beta.21

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 (291) hide show
  1. package/AUTHORING.md +487 -0
  2. package/CHANGELOG.md +90 -0
  3. package/README.md +49 -3
  4. package/SUBMISSION.md +1 -1
  5. package/bin/apifuse-check.ts +44 -59
  6. package/bin/apifuse-create.ts +1 -1
  7. package/bin/apifuse-dev.ts +27 -52
  8. package/bin/apifuse-pack-check.ts +14 -0
  9. package/bin/apifuse-pack-smoke.ts +36 -81
  10. package/bin/apifuse-pack-types.ts +305 -0
  11. package/bin/apifuse-perf.ts +45 -127
  12. package/bin/apifuse-record.ts +659 -111
  13. package/bin/apifuse-submit-check.ts +546 -48
  14. package/bin/apifuse-sync-assets.ts +117 -0
  15. package/bin/apifuse.ts +1 -1
  16. package/bin/submit-check-delimited-text.ts +50 -0
  17. package/bin/submit-check-xml-semantics.ts +204 -0
  18. package/bin/submit-check-xml.ts +134 -0
  19. package/dist/auth-turn/index.d.ts +3 -3
  20. package/dist/auth.d.ts +2 -2
  21. package/dist/auth.js +9 -18
  22. package/dist/ceremonies/index.d.ts +9 -1
  23. package/dist/ceremonies/index.js +65 -18
  24. package/dist/cli/commands.d.ts +1 -1
  25. package/dist/cli/commands.js +8 -0
  26. package/dist/cli/create.d.ts +3 -0
  27. package/dist/cli/create.js +34 -35
  28. package/dist/cli/prompt-assets.d.ts +80 -0
  29. package/dist/cli/prompt-assets.js +743 -0
  30. package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
  31. package/dist/config/loader.d.ts +176 -8
  32. package/dist/config/loader.js +424 -95
  33. package/dist/contract-serialization.d.ts +2 -2
  34. package/dist/contract-serialization.js +3 -6
  35. package/dist/contract-types.d.ts +2 -2
  36. package/dist/contract.d.ts +3 -3
  37. package/dist/contract.js +4 -6
  38. package/dist/define.d.ts +9 -1
  39. package/dist/define.js +304 -119
  40. package/dist/dev.d.ts +1 -1
  41. package/dist/dev.js +1 -1
  42. package/dist/error-resolution.d.ts +2 -0
  43. package/dist/error-resolution.js +90 -0
  44. package/dist/errors.d.ts +22 -1
  45. package/dist/errors.js +88 -0
  46. package/dist/fixture-sanitization.d.ts +26 -0
  47. package/dist/fixture-sanitization.js +216 -0
  48. package/dist/i18n/catalog.d.ts +2 -2
  49. package/dist/i18n/catalog.js +4 -10
  50. package/dist/i18n/index.d.ts +2 -2
  51. package/dist/i18n/index.js +2 -2
  52. package/dist/i18n/keys.d.ts +2 -2
  53. package/dist/index.d.ts +46 -42
  54. package/dist/index.js +41 -37
  55. package/dist/lint.d.ts +1 -1
  56. package/dist/lint.js +8 -15
  57. package/dist/native-address.d.ts +43 -0
  58. package/dist/native-address.js +281 -0
  59. package/dist/native-egress-policy.d.ts +31 -0
  60. package/dist/native-egress-policy.js +288 -0
  61. package/dist/observability.d.ts +5 -2
  62. package/dist/observability.js +48 -1
  63. package/dist/provider.d.ts +12 -11
  64. package/dist/provider.js +10 -9
  65. package/dist/public-schema-field-lint.d.ts +1 -1
  66. package/dist/recipes/gov-api.js +1 -1
  67. package/dist/runtime/auth-flow.d.ts +2 -1
  68. package/dist/runtime/auth-flow.js +4 -3
  69. package/dist/runtime/browser.d.ts +1 -1
  70. package/dist/runtime/browser.js +15 -29
  71. package/dist/runtime/cache.d.ts +1 -1
  72. package/dist/runtime/cache.js +4 -8
  73. package/dist/runtime/choice.d.ts +1 -1
  74. package/dist/runtime/choice.js +31 -35
  75. package/dist/runtime/credential.d.ts +1 -1
  76. package/dist/runtime/credential.js +1 -1
  77. package/dist/runtime/env.d.ts +1 -1
  78. package/dist/runtime/executor.d.ts +1 -1
  79. package/dist/runtime/executor.js +31 -4
  80. package/dist/runtime/http.d.ts +2 -2
  81. package/dist/runtime/http.js +387 -47
  82. package/dist/runtime/insights.d.ts +1 -1
  83. package/dist/runtime/insights.js +6 -13
  84. package/dist/runtime/instrumentation.d.ts +2 -2
  85. package/dist/runtime/instrumentation.js +345 -22
  86. package/dist/runtime/keyring.js +1 -1
  87. package/dist/runtime/namespace.js +1 -1
  88. package/dist/runtime/native-network.d.ts +127 -0
  89. package/dist/runtime/native-network.js +1298 -0
  90. package/dist/runtime/otlp.d.ts +1 -1
  91. package/dist/runtime/perf.d.ts +1 -1
  92. package/dist/runtime/provider.d.ts +1 -1
  93. package/dist/runtime/provider.js +1 -2
  94. package/dist/runtime/proxy-errors.d.ts +1 -1
  95. package/dist/runtime/proxy-errors.js +9 -7
  96. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  97. package/dist/runtime/proxy-nodemaven.js +146 -0
  98. package/dist/runtime/proxy-retry-policy.d.ts +2 -2
  99. package/dist/runtime/proxy-retry-policy.js +2 -2
  100. package/dist/runtime/proxy-telemetry.d.ts +2 -1
  101. package/dist/runtime/proxy-telemetry.js +55 -52
  102. package/dist/runtime/redirects.d.ts +29 -0
  103. package/dist/runtime/redirects.js +36 -0
  104. package/dist/runtime/redis.d.ts +1 -1
  105. package/dist/runtime/redis.js +2 -4
  106. package/dist/runtime/request-options.d.ts +68 -1
  107. package/dist/runtime/request-options.js +548 -0
  108. package/dist/runtime/secrets.d.ts +27 -0
  109. package/dist/runtime/secrets.js +51 -0
  110. package/dist/runtime/state.d.ts +2 -2
  111. package/dist/runtime/state.js +238 -26
  112. package/dist/runtime/stealth.d.ts +5 -3
  113. package/dist/runtime/stealth.js +423 -143
  114. package/dist/runtime/stt.d.ts +1 -1
  115. package/dist/runtime/stt.js +11 -15
  116. package/dist/runtime/trace.d.ts +2 -2
  117. package/dist/runtime/trace.js +2 -4
  118. package/dist/runtime/waterfall.d.ts +1 -1
  119. package/dist/schema.d.ts +1 -1
  120. package/dist/schema.js +7 -15
  121. package/dist/serve.d.ts +1 -1
  122. package/dist/serve.js +1 -1
  123. package/dist/server/index.d.ts +7 -7
  124. package/dist/server/index.js +6 -6
  125. package/dist/server/self-test-input-tokens.d.ts +2 -1
  126. package/dist/server/self-test-input-tokens.js +18 -14
  127. package/dist/server/self-test-redaction.d.ts +1 -1
  128. package/dist/server/self-test-redaction.js +1 -1
  129. package/dist/server/self-test.d.ts +104 -3
  130. package/dist/server/self-test.js +673 -115
  131. package/dist/server/serve.d.ts +116 -4
  132. package/dist/server/serve.js +799 -128
  133. package/dist/server/types.d.ts +34 -9
  134. package/dist/server/types.js +8 -1
  135. package/dist/stateful/errors.d.ts +14 -0
  136. package/dist/stateful/errors.js +14 -0
  137. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  138. package/dist/stateful/http-provider-event-emitter.js +237 -0
  139. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  140. package/dist/stateful/http-session-owner-registry.js +210 -0
  141. package/dist/stateful/index.d.ts +18 -0
  142. package/dist/stateful/index.js +18 -0
  143. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  144. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  145. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  146. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  147. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  148. package/dist/stateful/provider-event-pipeline.js +1 -0
  149. package/dist/stateful/provider-events.d.ts +101 -0
  150. package/dist/stateful/provider-events.js +289 -0
  151. package/dist/stateful/session-key.d.ts +15 -0
  152. package/dist/stateful/session-key.js +86 -0
  153. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  154. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  155. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  156. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  157. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  158. package/dist/stateful/stateful-provider-adapter.js +287 -0
  159. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  160. package/dist/stateful/stateful-provider-observability.js +161 -0
  161. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  162. package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
  163. package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
  164. package/dist/stateful/stateful-provider-runtime-context.js +60 -0
  165. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  166. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  167. package/dist/stateful/stateful-provider-session-routing.d.ts +71 -0
  168. package/dist/stateful/stateful-provider-session-routing.js +353 -0
  169. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  170. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  171. package/dist/stateful-signing.d.ts +18 -0
  172. package/dist/stateful-signing.js +27 -0
  173. package/dist/stealth/profiles.d.ts +1 -1
  174. package/dist/stealth/profiles.js +5 -14
  175. package/dist/stream-evidence.d.ts +74 -0
  176. package/dist/stream-evidence.js +785 -0
  177. package/dist/stream.d.ts +1 -1
  178. package/dist/testing/index.d.ts +2 -2
  179. package/dist/testing/index.js +2 -2
  180. package/dist/testing/run.d.ts +32 -2
  181. package/dist/testing/run.js +478 -28
  182. package/dist/types.d.ts +342 -14
  183. package/dist/types.js +1 -0
  184. package/dist/user-input.d.ts +30 -0
  185. package/dist/user-input.js +66 -0
  186. package/package.json +16 -5
  187. package/src/auth-turn/index.ts +1 -1
  188. package/src/auth.ts +28 -86
  189. package/src/ceremonies/index.ts +103 -78
  190. package/src/cli/commands.ts +10 -0
  191. package/src/cli/create.ts +42 -35
  192. package/src/cli/prompt-assets.ts +865 -0
  193. package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
  194. package/src/config/loader.ts +652 -204
  195. package/src/contract-serialization.ts +5 -11
  196. package/src/contract-types.ts +2 -2
  197. package/src/contract.ts +12 -28
  198. package/src/define.ts +499 -498
  199. package/src/dev.ts +4 -9
  200. package/src/error-resolution.ts +91 -0
  201. package/src/errors.ts +110 -5
  202. package/src/fixture-sanitization.ts +247 -0
  203. package/src/i18n/catalog.ts +10 -32
  204. package/src/i18n/index.ts +2 -2
  205. package/src/i18n/keys.ts +5 -11
  206. package/src/index.ts +112 -42
  207. package/src/lint.ts +88 -152
  208. package/src/native-address.ts +340 -0
  209. package/src/native-egress-policy.ts +358 -0
  210. package/src/observability.ts +51 -1
  211. package/src/provider.ts +66 -11
  212. package/src/public-schema-field-lint.ts +7 -33
  213. package/src/recipes/gov-api.ts +2 -5
  214. package/src/runtime/auth-flow.ts +7 -7
  215. package/src/runtime/browser.ts +64 -187
  216. package/src/runtime/cache.ts +20 -67
  217. package/src/runtime/choice.ts +79 -132
  218. package/src/runtime/credential.ts +2 -2
  219. package/src/runtime/env.ts +1 -1
  220. package/src/runtime/executor.ts +43 -20
  221. package/src/runtime/http.ts +494 -57
  222. package/src/runtime/insights.ts +15 -53
  223. package/src/runtime/instrumentation.ts +495 -66
  224. package/src/runtime/keyring.ts +7 -19
  225. package/src/runtime/namespace.ts +2 -7
  226. package/src/runtime/native-network.ts +1686 -0
  227. package/src/runtime/otlp.ts +12 -23
  228. package/src/runtime/perf.ts +1 -1
  229. package/src/runtime/provider.ts +4 -9
  230. package/src/runtime/proxy-errors.ts +29 -42
  231. package/src/runtime/proxy-nodemaven.ts +221 -0
  232. package/src/runtime/proxy-retry-policy.ts +3 -3
  233. package/src/runtime/proxy-telemetry.ts +79 -77
  234. package/src/runtime/redirects.ts +66 -0
  235. package/src/runtime/redis.ts +4 -12
  236. package/src/runtime/request-options.ts +679 -9
  237. package/src/runtime/secrets.ts +64 -0
  238. package/src/runtime/state.ts +353 -133
  239. package/src/runtime/stealth.ts +505 -154
  240. package/src/runtime/stt.ts +38 -94
  241. package/src/runtime/trace.ts +14 -44
  242. package/src/runtime/waterfall.ts +5 -18
  243. package/src/schema.ts +23 -84
  244. package/src/serve.ts +1 -1
  245. package/src/server/index.ts +29 -7
  246. package/src/server/self-test-input-tokens.ts +29 -14
  247. package/src/server/self-test-redaction.ts +2 -2
  248. package/src/server/self-test.ts +857 -132
  249. package/src/server/serve.ts +1151 -328
  250. package/src/server/types.ts +12 -13
  251. package/src/stateful/README.md +146 -0
  252. package/src/stateful/errors.ts +23 -0
  253. package/src/stateful/http-provider-event-emitter.ts +314 -0
  254. package/src/stateful/http-session-owner-registry.ts +306 -0
  255. package/src/stateful/index.ts +18 -0
  256. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  257. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  258. package/src/stateful/provider-event-pipeline.ts +61 -0
  259. package/src/stateful/provider-events.ts +462 -0
  260. package/src/stateful/session-key.ts +111 -0
  261. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  262. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  263. package/src/stateful/stateful-provider-adapter.ts +562 -0
  264. package/src/stateful/stateful-provider-observability.ts +261 -0
  265. package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
  266. package/src/stateful/stateful-provider-runtime-context.ts +92 -0
  267. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  268. package/src/stateful/stateful-provider-session-routing.ts +555 -0
  269. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  270. package/src/stateful-signing.ts +46 -0
  271. package/src/stealth/profiles.ts +10 -26
  272. package/src/stream-evidence.ts +988 -0
  273. package/src/stream.ts +8 -19
  274. package/src/testing/index.ts +10 -2
  275. package/src/testing/run.ts +653 -74
  276. package/src/types.ts +408 -28
  277. package/src/user-input.ts +118 -0
  278. package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
  279. package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
  280. /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  281. /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  282. /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  283. /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  284. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  285. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
  286. /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  287. /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  288. /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  289. /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  290. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  291. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
package/dist/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type ms from "ms";
2
+ import type { SerializedCookieJar } from "tough-cookie";
2
3
  import type { infer as ZodInfer, ZodType } from "zod";
3
4
  /** Minimal Standard Schema v1 shape accepted by provider operations. */
4
5
  export interface StandardSchemaV1<Input = unknown, Output = Input> {
@@ -46,6 +47,8 @@ export interface OperationToolRouterMetadata {
46
47
  riskClass?: OperationRiskClass;
47
48
  /** OpenAI remote-MCP approval hint. Defaults from riskClass. */
48
49
  approval?: OperationApprovalPolicy;
50
+ /** Canonical operation-level connection requirement consumed by the registry and Gateway. */
51
+ connectionMode?: "none" | "optional" | "required";
49
52
  /** Override connection requirement when provider auth + openWorld inference is insufficient. */
50
53
  requiresConnection?: boolean;
51
54
  /** Public argument used to resolve the tenant-owned connection. Defaults to externalRef. */
@@ -609,9 +612,11 @@ export interface HealthMonitorProbeOverride {
609
612
  /** Optional degraded threshold override for generated registry probes. */
610
613
  degradedThresholdMs?: number;
611
614
  }
615
+ export declare const VALID_OPERATION_ERROR_STATUSES: readonly [400, 401, 404, 409, 410, 422, 429, 500, 502, 503, 504];
616
+ export type ProviderErrorStatus = (typeof VALID_OPERATION_ERROR_STATUSES)[number];
612
617
  export interface OperationErrorCode {
613
618
  code: string;
614
- status?: number;
619
+ status?: ProviderErrorStatus;
615
620
  description: string;
616
621
  retryable?: boolean;
617
622
  }
@@ -645,12 +650,30 @@ export interface StealthProfile {
645
650
  h2Settings?: Record<string, unknown>;
646
651
  headerOrder?: string[];
647
652
  }
648
- export type AuthMode = "none" | "platform-managed" | "credentials" | "oauth2";
653
+ export type AuthMode = "none" | "platform-managed" | "credentials" | "oauth2" | "oauth2_proxied";
649
654
  export type ConnectionMode = AuthMode;
650
655
  export type ProviderReviewed = "first-party" | "community" | "staging";
651
656
  export type ProviderAccessVisibility = "public" | "early_access";
652
657
  export type ProviderProxyMode = "disabled" | "optional" | "required";
653
- export type ProviderProxyProvider = "smartproxy" | "decodo" | "custom";
658
+ /**
659
+ * Proxy egress vendors. These are FOUR DISTINCT services — do not conflate them
660
+ * (a common mistake because the names collide with a well-known rebrand):
661
+ *
662
+ * - `smartproxy` — **api.smartproxy.org**, a residential proxy with an IP
663
+ * *extraction/allocation* API (app_key → a pool of raw `ip:port` CONNECT
664
+ * endpoints). This is our own vendor. It is NOT the company formerly named
665
+ * "Smartproxy". Credentials: `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
666
+ * - `nodemaven` — **gate.nodemaven.com**, a *gateway* proxy with static
667
+ * credentials; geo/session encoded in the username, no allocation API.
668
+ * - `decodo` — **decodo.com**, the *gateway* proxy that was named "Smartproxy"
669
+ * (smartproxy.com) before its 2025 rebrand to Decodo. Sticky sessions via
670
+ * username params. A different company from `smartproxy` above.
671
+ * **@deprecated** — unused; no managed adapter. Use `smartproxy`/`nodemaven`,
672
+ * or the `APIFUSE__PROXY__URL` bring-your-own escape hatch.
673
+ * - `custom` — **@deprecated** bring-your-own static proxy URL marker. The
674
+ * `APIFUSE__PROXY__URL` env still works without declaring this value.
675
+ */
676
+ export type ProviderProxyProvider = "smartproxy" | "nodemaven" | "decodo" | "custom";
654
677
  export type ProviderProxySessionAffinity = "request" | "operation" | "auth-flow" | "connection";
655
678
  export interface ProviderProxyPolicy {
656
679
  /**
@@ -658,7 +681,18 @@ export interface ProviderProxyPolicy {
658
681
  * certificate verification, and vendor allocator endpoints are SDK-owned.
659
682
  */
660
683
  mode: ProviderProxyMode;
684
+ /**
685
+ * @deprecated Use `providers: [...]` to declare an ordered vendor fallback
686
+ * chain. A single-element `providers` list is equivalent to this field.
687
+ */
661
688
  provider?: ProviderProxyProvider;
689
+ /**
690
+ * Ordered proxy-vendor fallback chain. The SDK tries each vendor in order and
691
+ * fails over to the next when a vendor lacks credentials or its allocation /
692
+ * transport is exhausted. When omitted, `provider` (or the platform default)
693
+ * is used as a single-vendor chain.
694
+ */
695
+ providers?: ProviderProxyProvider[];
662
696
  geo?: {
663
697
  /** ISO 3166-1 alpha-2 country code, for example KR or US. */
664
698
  country?: Iso3166Alpha2CountryCode;
@@ -669,6 +703,12 @@ export interface ProviderProxyPolicy {
669
703
  affinity?: ProviderProxySessionAffinity;
670
704
  lifetimeMinutes?: number;
671
705
  poolSize?: number;
706
+ /**
707
+ * Seconds before hard sticky expiry at which native connections receive
708
+ * the `expiring` event so the provider can drain and reconnect cleanly.
709
+ * Declared by the provider; the SDK does not assume a default cut point.
710
+ */
711
+ drainLeadSeconds?: number;
672
712
  };
673
713
  }
674
714
  export type ProviderProxyConfig = boolean | ProviderProxyPolicy;
@@ -677,9 +717,9 @@ export interface ProviderAccessConfig {
677
717
  * Provider-level rollout visibility.
678
718
  *
679
719
  * - `public`: visible in public docs/catalog/OpenAPI and callable through
680
- * the existing provider policy stack.
720
+ * the existing provider policy stack.
681
721
  * - `early_access`: hidden from public discovery and callable only when the
682
- * active customer organization has a provider-level access grant.
722
+ * active customer organization has a provider-level access grant.
683
723
  *
684
724
  * This is intentionally provider-level only. It does not alter auth mode,
685
725
  * operation schemas, health-check authoring, `openWorld`, or Connection
@@ -810,6 +850,11 @@ export interface HttpRetrySummary {
810
850
  export interface RequestOptions {
811
851
  headers?: Record<string, string>;
812
852
  params?: RequestParams;
853
+ /**
854
+ * Query parameters whose values contain credentials or other secret material.
855
+ * They are sent like `params`, but redacted from SDK errors, traces, and recorded fixtures.
856
+ */
857
+ sensitiveParams?: Record<string, string>;
813
858
  proxy?: string;
814
859
  timeout?: number;
815
860
  /**
@@ -818,12 +863,33 @@ export interface RequestOptions {
818
863
  */
819
864
  throwOnHttpError?: boolean;
820
865
  retry?: boolean | HttpRetryPreset | HttpRetryOptions;
866
+ /**
867
+ * Opt-in redirect-hop enforcement for ctx.http. When present, redirects are
868
+ * evaluated before the next request is issued. Existing callers that omit
869
+ * this policy retain the native fetch redirect behavior.
870
+ */
871
+ redirectPolicy?: HttpRedirectPolicy;
821
872
  }
873
+ export type RedirectRunReason = "completed" | "stopped" | "max_hops" | "missing_location" | "loop";
874
+ export type HttpRedirectPolicyMode = "same-origin";
875
+ export interface HttpRedirectPolicy {
876
+ /** Only follow redirects whose canonical scheme, host, and port match the initial URL. */
877
+ mode: HttpRedirectPolicyMode;
878
+ /** Maximum number of redirect hops that may be followed. Must be an integer from 0 to 20. */
879
+ maxHops: number;
880
+ }
881
+ export type HttpRedirectFailureReason = Exclude<RedirectRunReason, "completed">;
822
882
  export type HttpMethod = "HEAD" | "head" | "GET" | "get" | "POST" | "post" | "PUT" | "put" | "DELETE" | "delete" | "OPTIONS" | "options" | "TRACE" | "trace" | "PATCH" | "patch";
823
- export interface StealthFetchOptions extends RequestOptions {
883
+ export interface StealthFetchOptions extends Omit<RequestOptions, "redirectPolicy"> {
824
884
  method?: HttpMethod;
825
885
  body?: string | Buffer;
826
886
  redirect?: "follow" | "manual" | "error";
887
+ /**
888
+ * Maximum decoded response-body bytes to buffer. When set, the stealth
889
+ * transport aborts the response and throws `response_too_large` if the
890
+ * declared or streamed body exceeds this limit.
891
+ */
892
+ maxBodyBytes?: number;
827
893
  /**
828
894
  * Offsets policy-managed proxy pool selection for caller-managed retries.
829
895
  * Use when a request receives an upstream challenge page rather than a
@@ -843,17 +909,42 @@ export interface StealthFetchOptions extends RequestOptions {
843
909
  };
844
910
  }
845
911
  export interface CookieJar {
846
- get(name: string): string | undefined;
847
- getAll(): Record<string, string>;
848
- toString(): string;
849
- find?(predicate: (cookie: string) => boolean): string | undefined;
912
+ /** URL-less reads use the jar's response URL or session base URL. */
913
+ get(name: string, url?: string): string | undefined;
914
+ getAll(url?: string): Record<string, string>;
915
+ toString(url?: string): string;
916
+ find?(predicate: (cookie: string) => boolean, url?: string): string | undefined;
850
917
  }
918
+ /**
919
+ * Version 1 of the JSON-safe, attribute-preserving stealth cookie store.
920
+ * The nested jar is tough-cookie's serialized form and retains cookie origin,
921
+ * Path, Secure, expiry, host-only, and other RFC attributes.
922
+ */
923
+ export interface StealthCookieStoreV1 {
924
+ readonly version: 1;
925
+ readonly jar: SerializedCookieJar;
926
+ }
927
+ /** Cookie persistence formats understood by this SDK version. */
928
+ export type StealthCookieStore = StealthCookieStoreV1;
851
929
  export interface StealthSessionCookies extends CookieJar {
852
- has(name: string): boolean;
853
- setFromCookieStrings(cookieStrings: readonly string[]): void;
854
- toHeader(): string;
930
+ has(name: string, url?: string): boolean;
931
+ /** URL-less writes are scoped to the session base URL. */
932
+ setFromCookieStrings(cookieStrings: readonly string[], url?: string): void;
933
+ toHeader(url?: string): string;
934
+ /**
935
+ * Returns every cookie as a flat name/value map, collapsing duplicate names.
936
+ * @deprecated Use serialize() for lossless, attribute-preserving persistence.
937
+ */
855
938
  snapshot(): Record<string, string>;
939
+ /**
940
+ * Restores flat values as host-only, Path=/ cookies on the session base URL.
941
+ * @deprecated Use deserialize() with state produced by serialize().
942
+ */
856
943
  restore(cookies: Record<string, string>): void;
944
+ /** Returns a versioned, JSON-safe, attribute-preserving representation of every cookie. */
945
+ serialize(): StealthCookieStoreV1;
946
+ /** Replaces the jar with a previously serialized, attribute-preserving cookie store. */
947
+ deserialize(state: StealthCookieStore): void;
857
948
  clear(): void;
858
949
  }
859
950
  export interface DeclarativeStealthResponse {
@@ -895,8 +986,14 @@ export interface StealthRedirectRunOptions extends Omit<StealthFetchOptions, "re
895
986
  export interface StealthRedirectRunResult {
896
987
  final: StealthResponse;
897
988
  hops: StealthRedirectHop[];
898
- reason: "completed" | "stopped" | "max_hops" | "missing_location" | "loop";
989
+ reason: RedirectRunReason;
990
+ /**
991
+ * Complete flat view across all redirect hosts. Attributes and duplicate names are lost.
992
+ * @deprecated Use cookieStore for lossless persistence.
993
+ */
899
994
  cookies: Record<string, string>;
995
+ /** Versioned, attribute-preserving cookie state accumulated across the redirect chain. */
996
+ cookieStore: StealthCookieStoreV1;
900
997
  }
901
998
  export interface StealthSession {
902
999
  fetch(url: string, options?: StealthFetchOptions): Promise<StealthResponse>;
@@ -959,6 +1056,154 @@ export interface HttpClient {
959
1056
  stream(url: string, options?: RequestWithMethodOptions): Promise<HttpStreamResponse>;
960
1057
  sse(url: string, options?: RequestWithMethodOptions): Promise<AsyncIterable<SseMessage>>;
961
1058
  }
1059
+ /** Request-scoped file reference accepted by provider operation inputs. */
1060
+ export interface ProviderFileRef {
1061
+ readonly type: "request_file";
1062
+ readonly id: string;
1063
+ readonly filename: string;
1064
+ readonly mime_type?: string;
1065
+ readonly size: number;
1066
+ readonly sha256?: string;
1067
+ }
1068
+ /** File body resolved from a request-scoped {@link ProviderFileRef}. */
1069
+ export type ProviderResolvedFile = Omit<ProviderFileRef, "mime_type"> & {
1070
+ readonly mimeType?: string;
1071
+ arrayBuffer(): Promise<ArrayBuffer>;
1072
+ bytes(): Promise<Uint8Array>;
1073
+ stream(): ReadableStream<Uint8Array>;
1074
+ };
1075
+ /** Resolver supplied by runtimes that accept request-scoped file inputs. */
1076
+ export interface ProviderFilesContext {
1077
+ has(input: string | ProviderFileRef): boolean;
1078
+ resolve(input: string | ProviderFileRef): Promise<ProviderResolvedFile>;
1079
+ }
1080
+ export type NativeTcpTlsMode = "required" | "allowed" | "disabled";
1081
+ export interface NativeTcpPortRange {
1082
+ readonly start: number;
1083
+ readonly end: number;
1084
+ }
1085
+ /** Static native TCP egress declared by a provider. */
1086
+ export interface NativeTcpEgressRule {
1087
+ readonly host: string;
1088
+ readonly ports: readonly number[];
1089
+ readonly tls: NativeTcpTlsMode;
1090
+ }
1091
+ /**
1092
+ * Bounded native TCP egress discovered through a declared bootstrap endpoint.
1093
+ * Host suffixes are exact DNS suffixes, not wildcard patterns.
1094
+ * Dynamic rules must declare at least one target host selector through
1095
+ * targetHostSuffixes, targetIpv4Cidrs, and/or targetIpv6Cidrs. Literal grant
1096
+ * sources and targets match only same-family selectors (except exact
1097
+ * sourceHost); DNS names match only host/suffix selectors. IPv4-mapped and
1098
+ * IPv4-compatible IPv6 literals are authorized only by IPv4 CIDRs.
1099
+ *
1100
+ * Dynamic rules are ordered. The first rule whose source, target, port, and TLS
1101
+ * selectors match exclusively owns the grant; its ttlMs and maxGrants bounds
1102
+ * apply, and an exhausted/shorter rule never falls through to a later overlap.
1103
+ * Every rule must declare a source host selector, source port list/range, and
1104
+ * target port list/range; omitted ttlMs/maxGrants remain unbounded.
1105
+ */
1106
+ export interface NativeTcpDynamicEgressRule {
1107
+ readonly sourceHost?: string;
1108
+ readonly sourceHostSuffixes?: readonly string[];
1109
+ readonly sourceIpv4Cidrs?: readonly string[];
1110
+ readonly sourceIpv6Cidrs?: readonly string[];
1111
+ readonly sourcePorts?: readonly number[];
1112
+ readonly sourcePortRanges?: readonly NativeTcpPortRange[];
1113
+ readonly targetHostSuffixes?: readonly string[];
1114
+ readonly targetIpv4Cidrs?: readonly string[];
1115
+ readonly targetIpv6Cidrs?: readonly string[];
1116
+ readonly targetPorts?: readonly number[];
1117
+ readonly targetPortRanges?: readonly NativeTcpPortRange[];
1118
+ readonly tls: NativeTcpTlsMode;
1119
+ readonly ttlMs?: number;
1120
+ readonly maxGrants?: number;
1121
+ }
1122
+ /** Common TCP/TLS connection input supported by the native runtime. */
1123
+ export interface NativeNetworkConnectInput {
1124
+ readonly host: string;
1125
+ readonly port: number;
1126
+ readonly serverName?: string;
1127
+ readonly rejectUnauthorized?: boolean;
1128
+ /**
1129
+ * Maximum time without a successful socket read before the connection is
1130
+ * closed. Opt-in; when absent, reads can remain pending indefinitely.
1131
+ */
1132
+ readonly idleTimeoutMs?: number;
1133
+ /** Maximum time allowed to establish the TCP/SOCKS/TLS connection. */
1134
+ readonly timeoutMs?: number;
1135
+ readonly signal?: AbortSignal;
1136
+ /** Overrides the credential-derived sticky affinity key. */
1137
+ readonly affinityKey?: string;
1138
+ }
1139
+ export type NativeNetworkConnectOptions = Omit<NativeNetworkConnectInput, "serverName" | "rejectUnauthorized">;
1140
+ export type NativeTlsConnectOptions = NativeNetworkConnectInput;
1141
+ export interface NativeNetworkDynamicGrantOptions {
1142
+ readonly sourceHost: string;
1143
+ readonly sourcePort: number;
1144
+ readonly host: string;
1145
+ readonly port: number;
1146
+ readonly tls: NativeTcpTlsMode;
1147
+ readonly ttlMs?: number;
1148
+ }
1149
+ export interface NativeNetworkEgressGrant {
1150
+ revoke(): void;
1151
+ }
1152
+ /** Consumer-facing alias used by native TCP providers. */
1153
+ export type NativeTcpEgressGrant = NativeNetworkEgressGrant;
1154
+ /** Resolved egress identity for a native connection routed through a proxy. */
1155
+ export interface NativeProxyEgressInfo {
1156
+ readonly vendor: ProviderProxyProvider;
1157
+ readonly sticky: boolean;
1158
+ /** Vendor sticky session id (sid). Absent for rotating sessions. */
1159
+ readonly sessionId?: string;
1160
+ /** Hard expiry of the sticky binding, ISO 8601. */
1161
+ readonly expiresAt?: string;
1162
+ }
1163
+ export type NativeProxyExpiringReason = "sticky_expiry";
1164
+ export interface NativeProxyExpiringEvent {
1165
+ readonly expiresAt: string;
1166
+ readonly leadSeconds: number;
1167
+ readonly reason: NativeProxyExpiringReason;
1168
+ }
1169
+ /**
1170
+ * Cooperative drain handler. The SDK awaits this before closing a socket whose
1171
+ * sticky proxy binding is about to expire, then force-closes at hard expiry.
1172
+ */
1173
+ export type NativeProxyDrainHandler = (event: NativeProxyExpiringEvent) => void | Promise<void>;
1174
+ /** Typed reason recorded when the SDK closes a native connection intentionally. */
1175
+ export interface NativeNetworkCloseReason {
1176
+ readonly code: string;
1177
+ readonly message: string;
1178
+ }
1179
+ /** Byte-oriented connection returned by the native TCP/TLS runtime. */
1180
+ export interface NativeNetworkConnection {
1181
+ /** Present when the connection was routed through a proxy. */
1182
+ readonly proxy?: NativeProxyEgressInfo;
1183
+ /** Present after an SDK-planned close, such as sticky proxy expiry. */
1184
+ readonly closeReason?: NativeNetworkCloseReason;
1185
+ /** Register a cooperative drain handler for sticky-expiry reconnects. */
1186
+ onExpiring?(handler: NativeProxyDrainHandler): void;
1187
+ read(): Promise<Uint8Array | null>;
1188
+ write(data: Uint8Array): Promise<void>;
1189
+ close(): Promise<void>;
1190
+ }
1191
+ export interface NativeNetworkClient {
1192
+ connectTcp(input: NativeNetworkConnectOptions): Promise<NativeNetworkConnection>;
1193
+ connectTls(input: NativeTlsConnectOptions): Promise<NativeNetworkConnection>;
1194
+ grantTcpEgress(input: NativeNetworkDynamicGrantOptions): NativeNetworkEgressGrant;
1195
+ }
1196
+ export interface NativeContext {
1197
+ readonly network: NativeNetworkClient;
1198
+ }
1199
+ /** Consumer-facing alias for the native capability on provider contexts. */
1200
+ export type NativeProviderContext = NativeContext;
1201
+ export interface NativeProviderConfig {
1202
+ readonly network?: {
1203
+ readonly tcp?: readonly NativeTcpEgressRule[];
1204
+ readonly dynamicTcp?: readonly NativeTcpDynamicEgressRule[];
1205
+ };
1206
+ }
962
1207
  export interface ProviderCacheKeyOptions {
963
1208
  /**
964
1209
  * Additional field names to omit from stable key material. The SDK always
@@ -1285,11 +1530,15 @@ export interface AuthFlowTerminalContext {
1285
1530
  }): AuthTurn;
1286
1531
  }
1287
1532
  export interface FlowContext {
1533
+ /** Gateway auth-flow id. Required by flow-scoped auth ceremonies. */
1534
+ flowId?: string;
1288
1535
  connectionId?: string;
1289
1536
  externalRef?: string;
1290
1537
  tenantId: string;
1291
1538
  providerId: string;
1292
1539
  http: HttpClient;
1540
+ /** Present when the selected runtime supplies native network capabilities. */
1541
+ readonly native?: NativeProviderContext;
1293
1542
  stealth: StealthClient;
1294
1543
  env: EnvContext;
1295
1544
  credential?: CredentialContext;
@@ -1375,6 +1624,10 @@ export interface ProviderContext {
1375
1624
  credential: CredentialContext;
1376
1625
  request?: ProviderRequestContext;
1377
1626
  http: HttpClient;
1627
+ /** Present for requests carrying runtime-resolvable file references. */
1628
+ readonly files?: ProviderFilesContext;
1629
+ /** Present when the selected runtime supplies native network capabilities. */
1630
+ readonly native?: NativeProviderContext;
1378
1631
  cache: ProviderCache;
1379
1632
  state: ProviderRuntimeState;
1380
1633
  stealth: StealthClient;
@@ -1384,8 +1637,20 @@ export interface ProviderContext {
1384
1637
  stt: SttContext;
1385
1638
  choice: ProviderChoiceContext;
1386
1639
  }
1640
+ export interface ProxiedOAuthConfig {
1641
+ authorizeUrl: string;
1642
+ tokenUrl: string;
1643
+ customScheme: string;
1644
+ rewriteProfile: string;
1645
+ clientIdEnvKey: string;
1646
+ pkce?: "S256" | "none";
1647
+ authorizeParams?: Record<string, string>;
1648
+ tokenParams?: Record<string, string>;
1649
+ }
1387
1650
  export interface AuthConfig {
1388
1651
  mode: AuthMode;
1652
+ /** Browser reverse-proxy contract for providers with custom-scheme OAuth callbacks. */
1653
+ proxied?: ProxiedOAuthConfig;
1389
1654
  flow?: AuthFlowDefinition;
1390
1655
  }
1391
1656
  export interface ProviderSecretDeclaration {
@@ -1418,6 +1683,19 @@ export interface OperationContractMetadata {
1418
1683
  deprecation?: OperationDeprecationMetadata;
1419
1684
  }
1420
1685
  export interface OperationDefinition<TInput extends SchemaLike = SchemaLike, TOutput extends SchemaLike = SchemaLike> {
1686
+ /**
1687
+ * Short English display title for the operation. The SDK passes it through
1688
+ * verbatim; the APIFuse registry derives the operation's en locale title
1689
+ * baseline from it (`docs.titleKey` remains available as an explicit key
1690
+ * override).
1691
+ */
1692
+ title?: string;
1693
+ /**
1694
+ * Raw English operation description. The SDK passes it through verbatim;
1695
+ * keyed descriptions via `descriptionKey` remain the primary flow, and
1696
+ * provider lint rules for raw prose descriptions still apply.
1697
+ */
1698
+ description?: string;
1421
1699
  descriptionKey?: ProviderLocaleKeyInput;
1422
1700
  docs?: OperationDocMeta;
1423
1701
  whenToUseKeys?: readonly ProviderLocaleKeyInput[];
@@ -1438,6 +1716,11 @@ export interface OperationDefinition<TInput extends SchemaLike = SchemaLike, TOu
1438
1716
  fixtures?: {
1439
1717
  request: InferSchemaOutput<TInput>;
1440
1718
  response: InferSchemaOutput<TOutput>;
1719
+ /**
1720
+ * KST calendar date when `response` evidence was captured. Date fields in
1721
+ * the response align with this date, not a resolved relative request date.
1722
+ */
1723
+ recordedAt?: string;
1441
1724
  };
1442
1725
  upstream?: {
1443
1726
  baseUrl?: string;
@@ -1447,11 +1730,56 @@ export interface OperationDefinition<TInput extends SchemaLike = SchemaLike, TOu
1447
1730
  healthCheck?: HealthCheckSuite<InferSchemaOutput<TInput>, InferSchemaOutput<TOutput>>;
1448
1731
  healthCheckUnsupported?: HealthCheckUnsupported;
1449
1732
  }
1733
+ /**
1734
+ * Author-declared deployment overrides accepted as the optional top-level
1735
+ * `deployment` key on `defineProvider()`.
1736
+ *
1737
+ * The SDK passes this object through VERBATIM onto the returned provider
1738
+ * definition — it is typed here but deliberately not deep-validated: the
1739
+ * APIFuse registry builder owns deployment validation and resolves omitted
1740
+ * fields against the runtime deployment profiles. The shape mirrors the
1741
+ * registry's `ProviderDeploymentOverrides` contract; every field is
1742
+ * optional. Note that the deployment `runtime` axis
1743
+ * (`shared`/`dedicated`/`browser`) is distinct from the provider execution
1744
+ * `runtime` (`standard`/`shared`/`browser`).
1745
+ */
1746
+ export interface ProviderDeploymentOverrides {
1747
+ runtime?: "shared" | "dedicated" | "browser";
1748
+ language?: "typescript" | "python";
1749
+ replicas?: number;
1750
+ hpa?: {
1751
+ enabled: boolean;
1752
+ minReplicas?: number;
1753
+ maxReplicas?: number;
1754
+ targetCPUUtilizationPercentage?: number;
1755
+ };
1756
+ resources?: {
1757
+ cpu: string;
1758
+ memory: string;
1759
+ };
1760
+ cache?: {
1761
+ redis?: {
1762
+ enabled: boolean;
1763
+ url?: string;
1764
+ };
1765
+ };
1766
+ network?: {
1767
+ additionalTcpPorts?: number[];
1768
+ };
1769
+ buildContext?: string;
1770
+ }
1450
1771
  export interface ProviderDefinition {
1451
1772
  id: string;
1452
1773
  version: string;
1453
1774
  runtime: "standard" | "shared" | "browser";
1775
+ /**
1776
+ * Optional deployment overrides, passed through verbatim from
1777
+ * `defineProvider({ deployment })`. Validation and profile resolution are
1778
+ * owned by the APIFuse registry builder, not the SDK.
1779
+ */
1780
+ deployment?: ProviderDeploymentOverrides;
1454
1781
  allowedHosts?: string[];
1782
+ native?: NativeProviderConfig;
1455
1783
  stealth?: {
1456
1784
  profile: string;
1457
1785
  platform: StealthPlatform;
package/dist/types.js CHANGED
@@ -32,6 +32,7 @@ export const HEALTH_CHECK_TIMEOUT_MS_MIN = 1;
32
32
  export const HEALTH_CHECK_TIMEOUT_MS_MAX = 60_000;
33
33
  export const HEALTH_CHECK_DEGRADED_THRESHOLD_MS_MIN = 1;
34
34
  export const HEALTH_CHECK_DEGRADED_THRESHOLD_MS_MAX = 60_000;
35
+ export const VALID_OPERATION_ERROR_STATUSES = [400, 401, 404, 409, 410, 422, 429, 500, 502, 503, 504];
35
36
  export const HttpRetryPreset = {
36
37
  Off: "off",
37
38
  TransportTransient: "transport_transient",
@@ -0,0 +1,30 @@
1
+ export declare const NEEDS_INPUT_STATUS: "needs_input";
2
+ export interface ProviderSelectionOption {
3
+ readonly selection_value: string;
4
+ readonly label: string;
5
+ readonly [extra: string]: unknown;
6
+ }
7
+ export interface ProviderRequiredSelection {
8
+ readonly selection_key: string;
9
+ readonly label: string;
10
+ readonly required: boolean;
11
+ readonly selection_type?: string;
12
+ readonly valid_options: readonly ProviderSelectionOption[];
13
+ readonly [extra: string]: unknown;
14
+ }
15
+ export interface ProviderSelectedOption {
16
+ readonly selection_key: string;
17
+ readonly selection_value: string;
18
+ /** Free-text answer for text-kind selections. */
19
+ readonly text?: string;
20
+ /** Quantity for quantity-kind selections. */
21
+ readonly quantity?: number;
22
+ }
23
+ export interface ProviderNeedsInputPayload {
24
+ readonly status: typeof NEEDS_INPUT_STATUS;
25
+ readonly required_selections: readonly ProviderRequiredSelection[];
26
+ readonly selected_options?: readonly ProviderSelectedOption[];
27
+ /** Provider-specific fresh state token(s), e.g. `reservation_state`. */
28
+ readonly [extra: string]: unknown;
29
+ }
30
+ export declare function isProviderNeedsInputPayload(value: unknown): value is ProviderNeedsInputPayload;
@@ -0,0 +1,66 @@
1
+ // Official cross-provider contract for user-input round-trips.
2
+ //
3
+ // Doctrine (born from the 2026-07-20 CatchTable reserve incident): an
4
+ // operation MUST NOT dead-end on a problem the end user can resolve by
5
+ // choosing among live options. Instead of throwing, the provider returns a
6
+ // SUCCESSFUL payload with `status: "needs_input"` that carries everything a
7
+ // consumer-side agent needs to relay the choice verbatim and retry:
8
+ //
9
+ // - `required_selections`: only the still-pending questions, each with
10
+ // human-readable `label`s and `valid_options` the agent shows the user
11
+ // as-is. The agent never chooses on the user's behalf.
12
+ // - `selected_options`: selections already settled, echoed so the follow-up
13
+ // call keeps them without the agent reconstructing anything.
14
+ // - a fresh provider-specific state token (e.g. `reservation_state`) minted
15
+ // at response time, so the retry never races an expired token.
16
+ //
17
+ // Keeping this success-shaped (instead of error `details`) is deliberate:
18
+ // consumer error-shaping layers routinely strip error metadata, and a model
19
+ // that only sees "error" narrates failure to the user. Complex recovery
20
+ // logic belongs to the system, not the model.
21
+ //
22
+ // Deliberately ABSENT: retry templates, next-action routing, or any other
23
+ // agent choreography. Provider payloads carry upstream-backed data only; how
24
+ // to phrase the ask and shape the retry call is the consumer's contract
25
+ // (apifuse#1030). The retry is fully determined by data: copy the echoed
26
+ // selected_options, add the user's new answers, resend with the fresh state.
27
+ export const NEEDS_INPUT_STATUS = "needs_input";
28
+ function isRecord(value) {
29
+ return typeof value === "object" && value !== null && !Array.isArray(value);
30
+ }
31
+ function isSelectionOption(value) {
32
+ return (isRecord(value) &&
33
+ typeof value.selection_value === "string" &&
34
+ typeof value.label === "string");
35
+ }
36
+ function isRequiredSelection(value) {
37
+ return (isRecord(value) &&
38
+ typeof value.selection_key === "string" &&
39
+ typeof value.label === "string" &&
40
+ typeof value.required === "boolean" &&
41
+ Array.isArray(value.valid_options) &&
42
+ value.valid_options.every(isSelectionOption));
43
+ }
44
+ function isSelectedOption(value) {
45
+ return (isRecord(value) &&
46
+ typeof value.selection_key === "string" &&
47
+ typeof value.selection_value === "string");
48
+ }
49
+ export function isProviderNeedsInputPayload(value) {
50
+ if (!isRecord(value)) {
51
+ return false;
52
+ }
53
+ if (value.status !== NEEDS_INPUT_STATUS ||
54
+ !Array.isArray(value.required_selections) ||
55
+ !value.required_selections.every(isRequiredSelection)) {
56
+ return false;
57
+ }
58
+ // A needs_input with nothing to ask AND nothing settled to echo is a
59
+ // no-op dead end — reject it so providers cannot ship it accidentally.
60
+ if (value.required_selections.length > 0) {
61
+ return true;
62
+ }
63
+ return (Array.isArray(value.selected_options) &&
64
+ value.selected_options.length > 0 &&
65
+ value.selected_options.every(isSelectedOption));
66
+ }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.2.0-beta.2",
2
+ "version": "2.2.0-beta.21",
3
3
  "name": "@apifuse/provider-sdk",
4
4
  "private": false,
5
5
  "type": "module",
@@ -61,6 +61,11 @@
61
61
  "import": "./dist/server/index.js",
62
62
  "default": "./dist/server/index.js"
63
63
  },
64
+ "./stateful": {
65
+ "types": "./dist/stateful/index.d.ts",
66
+ "import": "./dist/stateful/index.js",
67
+ "default": "./dist/stateful/index.js"
68
+ },
64
69
  "./testing": {
65
70
  "types": "./dist/testing/index.d.ts",
66
71
  "import": "./dist/testing/index.js",
@@ -75,24 +80,28 @@
75
80
  "scripts": {
76
81
  "lint": "biome lint .",
77
82
  "lint:fix": "biome lint --write",
83
+ "lint:deprecated": "bun run scripts/lint-deprecated-usage.ts",
78
84
  "format": "biome format --write",
79
- "type-check": "tsgo --noEmit",
85
+ "type-check": "tsc --noEmit",
80
86
  "test": "bun test",
81
- "check": "bun run lint && bun run type-check && bun run build",
87
+ "check": "bun run lint && bun run type-check && bun run lint:deprecated && bun run build",
82
88
  "pack:check": "bun run build && bun bin/apifuse-pack-check.ts",
83
89
  "pack:smoke": "bun run build && bun bin/apifuse-pack-smoke.ts",
90
+ "pack:types": "bun run build && bun bin/apifuse-pack-types.ts",
84
91
  "release:guard": "bun scripts/guard-release-pr.ts",
85
92
  "format:check": "biome format .",
86
- "build": "tsgo -p tsconfig.build.json && rm -rf dist/cli/templates && cp -R src/cli/templates dist/cli/templates && rm -rf dist/auth-turn/fixtures && cp -R src/auth-turn/fixtures dist/auth-turn/fixtures && cp src/auth-turn/auth-turn.v1.schema.json dist/auth-turn/auth-turn.v1.schema.json"
93
+ "build": "tsc -p tsconfig.build.json && rm -rf dist/cli/templates && cp -R src/cli/templates dist/cli/templates && rm -rf dist/auth-turn/fixtures && cp -R src/auth-turn/fixtures dist/auth-turn/fixtures && cp src/auth-turn/auth-turn.v1.schema.json dist/auth-turn/auth-turn.v1.schema.json"
87
94
  },
88
95
  "devDependencies": {
96
+ "@arethetypeswrong/cli": "^0.18.5",
89
97
  "@biomejs/biome": "^2.5.0",
90
98
  "@types/bun": "latest",
91
99
  "@types/node": "^25.9.3",
92
- "@typescript/native-preview": "7.0.0-dev.20260419.1"
100
+ "typescript": "6.0.3"
93
101
  },
94
102
  "dependencies": {
95
103
  "@clack/prompts": "^1.5.1",
104
+ "@rgrove/parse-xml": "4.2.2",
96
105
  "@types/ms": "^2.1.0",
97
106
  "acorn": "^8.17.0",
98
107
  "ajv": "^8.17",
@@ -105,6 +114,8 @@
105
114
  "puppeteer-extra-plugin-stealth": "^2.11.2",
106
115
  "re2-wasm": "^1.0",
107
116
  "safe-regex": "^2.1",
117
+ "socks": "^2.8.9",
118
+ "tough-cookie": "^6.0.2",
108
119
  "zod": "^4.4.3"
109
120
  },
110
121
  "repository": {
@@ -1,4 +1,4 @@
1
- import type { AuthTurn } from "../types";
1
+ import type { AuthTurn } from "../types.js";
2
2
 
3
3
  export type { AuthTurn };
4
4