@apifuse/provider-sdk 2.2.0-beta.1 → 2.2.0-beta.11

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 (261) hide show
  1. package/AUTHORING.md +106 -0
  2. package/CHANGELOG.md +41 -0
  3. package/README.md +5 -1
  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 +22 -81
  10. package/bin/apifuse-pack-types.ts +266 -0
  11. package/bin/apifuse-perf.ts +45 -127
  12. package/bin/apifuse-record.ts +53 -70
  13. package/bin/apifuse-submit-check.ts +510 -45
  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 +1 -1
  23. package/dist/ceremonies/index.js +8 -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 +149 -8
  32. package/dist/config/loader.js +378 -89
  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 +8 -1
  39. package/dist/define.js +119 -122
  40. package/dist/dev.d.ts +1 -1
  41. package/dist/dev.js +1 -1
  42. package/dist/errors.d.ts +4 -1
  43. package/dist/errors.js +48 -0
  44. package/dist/i18n/catalog.d.ts +2 -2
  45. package/dist/i18n/catalog.js +4 -10
  46. package/dist/i18n/index.d.ts +2 -2
  47. package/dist/i18n/index.js +2 -2
  48. package/dist/i18n/keys.d.ts +2 -2
  49. package/dist/index.d.ts +44 -42
  50. package/dist/index.js +39 -37
  51. package/dist/lint.js +8 -15
  52. package/dist/provider.d.ts +11 -11
  53. package/dist/provider.js +9 -9
  54. package/dist/public-schema-field-lint.d.ts +1 -1
  55. package/dist/recipes/gov-api.js +1 -1
  56. package/dist/runtime/auth-flow.d.ts +1 -1
  57. package/dist/runtime/auth-flow.js +3 -3
  58. package/dist/runtime/browser.d.ts +1 -1
  59. package/dist/runtime/browser.js +15 -29
  60. package/dist/runtime/cache.d.ts +1 -1
  61. package/dist/runtime/cache.js +4 -8
  62. package/dist/runtime/choice.d.ts +1 -1
  63. package/dist/runtime/choice.js +31 -35
  64. package/dist/runtime/credential.d.ts +1 -1
  65. package/dist/runtime/credential.js +1 -1
  66. package/dist/runtime/env.d.ts +1 -1
  67. package/dist/runtime/executor.d.ts +1 -1
  68. package/dist/runtime/executor.js +15 -3
  69. package/dist/runtime/http.d.ts +2 -2
  70. package/dist/runtime/http.js +144 -348
  71. package/dist/runtime/insights.d.ts +1 -1
  72. package/dist/runtime/insights.js +6 -13
  73. package/dist/runtime/instrumentation.d.ts +2 -2
  74. package/dist/runtime/instrumentation.js +56 -19
  75. package/dist/runtime/keyring.js +1 -1
  76. package/dist/runtime/namespace.js +1 -1
  77. package/dist/runtime/otlp.d.ts +1 -1
  78. package/dist/runtime/perf.d.ts +1 -1
  79. package/dist/runtime/provider.d.ts +1 -1
  80. package/dist/runtime/provider.js +1 -2
  81. package/dist/runtime/proxy-errors.d.ts +1 -1
  82. package/dist/runtime/proxy-errors.js +9 -7
  83. package/dist/runtime/proxy-nodemaven.d.ts +35 -0
  84. package/dist/runtime/proxy-nodemaven.js +128 -0
  85. package/dist/runtime/proxy-retry-policy.d.ts +40 -0
  86. package/dist/runtime/proxy-retry-policy.js +326 -0
  87. package/dist/runtime/proxy-telemetry.d.ts +2 -1
  88. package/dist/runtime/proxy-telemetry.js +55 -52
  89. package/dist/runtime/redis.d.ts +1 -1
  90. package/dist/runtime/redis.js +2 -4
  91. package/dist/runtime/request-options.d.ts +1 -1
  92. package/dist/runtime/secrets.d.ts +27 -0
  93. package/dist/runtime/secrets.js +51 -0
  94. package/dist/runtime/state.d.ts +2 -2
  95. package/dist/runtime/state.js +15 -4
  96. package/dist/runtime/stealth.d.ts +2 -2
  97. package/dist/runtime/stealth.js +108 -212
  98. package/dist/runtime/stt.d.ts +1 -1
  99. package/dist/runtime/stt.js +11 -15
  100. package/dist/runtime/trace.d.ts +2 -2
  101. package/dist/runtime/trace.js +2 -4
  102. package/dist/runtime/waterfall.d.ts +1 -1
  103. package/dist/schema.d.ts +1 -1
  104. package/dist/schema.js +7 -15
  105. package/dist/serve.d.ts +1 -1
  106. package/dist/serve.js +1 -1
  107. package/dist/server/index.d.ts +7 -7
  108. package/dist/server/index.js +6 -6
  109. package/dist/server/self-test-redaction.d.ts +1 -1
  110. package/dist/server/self-test-redaction.js +1 -1
  111. package/dist/server/self-test.d.ts +104 -3
  112. package/dist/server/self-test.js +673 -115
  113. package/dist/server/serve.d.ts +105 -4
  114. package/dist/server/serve.js +588 -80
  115. package/dist/server/types.d.ts +10 -9
  116. package/dist/server/types.js +3 -7
  117. package/dist/stateful/errors.d.ts +14 -0
  118. package/dist/stateful/errors.js +14 -0
  119. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  120. package/dist/stateful/http-provider-event-emitter.js +237 -0
  121. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  122. package/dist/stateful/http-session-owner-registry.js +210 -0
  123. package/dist/stateful/index.d.ts +18 -0
  124. package/dist/stateful/index.js +18 -0
  125. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  126. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  127. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  128. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  129. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  130. package/dist/stateful/provider-event-pipeline.js +1 -0
  131. package/dist/stateful/provider-events.d.ts +101 -0
  132. package/dist/stateful/provider-events.js +289 -0
  133. package/dist/stateful/session-key.d.ts +15 -0
  134. package/dist/stateful/session-key.js +86 -0
  135. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  136. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  137. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  138. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  139. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  140. package/dist/stateful/stateful-provider-adapter.js +287 -0
  141. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  142. package/dist/stateful/stateful-provider-observability.js +161 -0
  143. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  144. package/dist/stateful/stateful-provider-owner-forwarder.js +207 -0
  145. package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
  146. package/dist/stateful/stateful-provider-runtime-context.js +60 -0
  147. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  148. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  149. package/dist/stateful/stateful-provider-session-routing.d.ts +71 -0
  150. package/dist/stateful/stateful-provider-session-routing.js +353 -0
  151. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  152. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  153. package/dist/stateful-signing.d.ts +18 -0
  154. package/dist/stateful-signing.js +27 -0
  155. package/dist/stealth/profiles.d.ts +1 -1
  156. package/dist/stealth/profiles.js +5 -14
  157. package/dist/stream.d.ts +1 -1
  158. package/dist/testing/index.d.ts +2 -2
  159. package/dist/testing/index.js +2 -2
  160. package/dist/testing/run.d.ts +1 -1
  161. package/dist/testing/run.js +7 -14
  162. package/dist/types.d.ts +87 -1
  163. package/dist/user-input.d.ts +30 -0
  164. package/dist/user-input.js +66 -0
  165. package/package.json +14 -5
  166. package/src/auth-turn/index.ts +1 -1
  167. package/src/auth.ts +28 -86
  168. package/src/ceremonies/index.ts +24 -78
  169. package/src/cli/commands.ts +10 -0
  170. package/src/cli/create.ts +42 -35
  171. package/src/cli/prompt-assets.ts +865 -0
  172. package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
  173. package/src/config/loader.ts +543 -208
  174. package/src/contract-serialization.ts +5 -11
  175. package/src/contract-types.ts +2 -2
  176. package/src/contract.ts +12 -28
  177. package/src/define.ts +247 -505
  178. package/src/dev.ts +4 -9
  179. package/src/errors.ts +58 -5
  180. package/src/i18n/catalog.ts +10 -32
  181. package/src/i18n/index.ts +2 -2
  182. package/src/i18n/keys.ts +5 -11
  183. package/src/index.ts +49 -42
  184. package/src/lint.ts +89 -159
  185. package/src/provider.ts +15 -11
  186. package/src/public-schema-field-lint.ts +7 -33
  187. package/src/recipes/gov-api.ts +2 -5
  188. package/src/runtime/auth-flow.ts +5 -7
  189. package/src/runtime/browser.ts +64 -187
  190. package/src/runtime/cache.ts +20 -67
  191. package/src/runtime/choice.ts +79 -132
  192. package/src/runtime/credential.ts +2 -2
  193. package/src/runtime/env.ts +1 -1
  194. package/src/runtime/executor.ts +23 -20
  195. package/src/runtime/http.ts +195 -559
  196. package/src/runtime/insights.ts +15 -53
  197. package/src/runtime/instrumentation.ts +78 -65
  198. package/src/runtime/keyring.ts +7 -19
  199. package/src/runtime/namespace.ts +2 -7
  200. package/src/runtime/otlp.ts +12 -23
  201. package/src/runtime/perf.ts +1 -1
  202. package/src/runtime/provider.ts +4 -9
  203. package/src/runtime/proxy-errors.ts +29 -42
  204. package/src/runtime/proxy-nodemaven.ts +178 -0
  205. package/src/runtime/proxy-retry-policy.ts +469 -0
  206. package/src/runtime/proxy-telemetry.ts +79 -77
  207. package/src/runtime/redis.ts +4 -12
  208. package/src/runtime/request-options.ts +4 -13
  209. package/src/runtime/secrets.ts +64 -0
  210. package/src/runtime/state.ts +41 -110
  211. package/src/runtime/stealth.ts +162 -377
  212. package/src/runtime/stt.ts +38 -94
  213. package/src/runtime/trace.ts +14 -44
  214. package/src/runtime/waterfall.ts +5 -18
  215. package/src/schema.ts +23 -84
  216. package/src/serve.ts +1 -1
  217. package/src/server/index.ts +24 -7
  218. package/src/server/self-test-redaction.ts +2 -2
  219. package/src/server/self-test.ts +857 -132
  220. package/src/server/serve.ts +859 -266
  221. package/src/server/types.ts +7 -19
  222. package/src/stateful/README.md +146 -0
  223. package/src/stateful/errors.ts +23 -0
  224. package/src/stateful/http-provider-event-emitter.ts +314 -0
  225. package/src/stateful/http-session-owner-registry.ts +306 -0
  226. package/src/stateful/index.ts +18 -0
  227. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  228. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  229. package/src/stateful/provider-event-pipeline.ts +61 -0
  230. package/src/stateful/provider-events.ts +462 -0
  231. package/src/stateful/session-key.ts +111 -0
  232. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  233. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  234. package/src/stateful/stateful-provider-adapter.ts +562 -0
  235. package/src/stateful/stateful-provider-observability.ts +261 -0
  236. package/src/stateful/stateful-provider-owner-forwarder.ts +279 -0
  237. package/src/stateful/stateful-provider-runtime-context.ts +92 -0
  238. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  239. package/src/stateful/stateful-provider-session-routing.ts +555 -0
  240. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  241. package/src/stateful-signing.ts +46 -0
  242. package/src/stealth/profiles.ts +10 -26
  243. package/src/stream.ts +8 -19
  244. package/src/testing/index.ts +2 -2
  245. package/src/testing/run.ts +19 -67
  246. package/src/types.ts +88 -1
  247. package/src/user-input.ts +118 -0
  248. package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
  249. package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
  250. /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  251. /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  252. /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  253. /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  254. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  255. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
  256. /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  257. /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  258. /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  259. /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  260. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  261. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
@@ -1,6 +1,6 @@
1
- import { providerStateRedisUrlFromEnv } from "../config/loader";
2
- import { ProviderError } from "../errors";
3
- import { createProviderRedisClient, ensureRedisReady, withRedisTimeout, } from "./redis";
1
+ import { providerStateRedisUrlFromEnv } from "../config/loader.js";
2
+ import { ProviderError } from "../errors.js";
3
+ import { createProviderRedisClient, ensureRedisReady, withRedisTimeout, } from "./redis.js";
4
4
  const DEFAULT_REDIS_TIMEOUT_MS = 250;
5
5
  const REDIS_STATE_PREFIX = "apifuse:provider-state:v1";
6
6
  const redisBackends = new Map();
@@ -69,7 +69,18 @@ function resolveExpiresAt(ttl) {
69
69
  function envelopeFromJson(key, raw) {
70
70
  if (!raw)
71
71
  return null;
72
- const parsed = JSON.parse(raw);
72
+ // A corrupt/undecodable persisted envelope must be treated as absent rather
73
+ // than throwing a raw JSON.parse SyntaxError: an uncaught SyntaxError escapes
74
+ // the provider error taxonomy, is masked as internal_error 500, and is then
75
+ // retried by the hub (2026-07-22 catchtable reserve RCA, candidate A). Returning
76
+ // null also keeps list() from aborting the whole scan on a single bad entry.
77
+ let parsed;
78
+ try {
79
+ parsed = JSON.parse(raw);
80
+ }
81
+ catch {
82
+ return null;
83
+ }
73
84
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
74
85
  return null;
75
86
  }
@@ -1,6 +1,6 @@
1
1
  import type { ImpitResponse } from "impit";
2
- import type { ProxyResolutionOptions } from "../config/loader";
3
- import type { StealthClient, StealthResponse } from "../types";
2
+ import type { ProxyResolutionOptions } from "../config/loader.js";
3
+ import type { StealthClient, StealthResponse } from "../types.js";
4
4
  export type StealthClientOptions = ProxyResolutionOptions & {
5
5
  warn?: (message: string) => void;
6
6
  /**
@@ -1,44 +1,19 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { Impit } from "impit";
3
- import { DEFAULT_SMARTPROXY_POOL_SIZE, invalidateProxyResolutionCacheAsync, ProxyResolutionError, resolveProxyConfigAsync, SMARTPROXY_MAX_POOL_SIZE, } from "../config/loader";
4
- import { ProviderError, SDKError, TransportError } from "../errors";
5
- import { getStealthProfile } from "../stealth/profiles";
6
- import { HttpRetryPreset, HttpRetryUnsafeMethodPolicy } from "../types";
7
- import { createProxyAuthIpDeniedError, createProxyEdgeAuthRejectedError, createProxyEdgeTlsRejectedError, createProxyPoolExhaustedError, createProxyPoolStaleError, isProxyAuthIpDeniedMessage, isProxyEdgeAuthRejectedMessage, isProxyEdgeTlsRejectedResponse, isProxyPoolRefreshableError, isProxyPoolStaleMessage, isProxyPoolStaleStatus, PROXY_AUTH_IP_DENIED_CODE, PROXY_EDGE_AUTH_REJECTED_CODE, PROXY_POOL_STALE_CODE, } from "./proxy-errors";
8
- import { appendQueryParams } from "./request-options";
3
+ import { DEFAULT_SMARTPROXY_POOL_SIZE, invalidateProxyResolutionCacheAsync, policyResolvesRegistryVendorChain, ProxyResolutionError, resolvePolicyProxyPoolSpan, resolvePolicyTransportAttemptCap, resolveProxyConfigAsync, vendorFromResolvedSource, } from "../config/loader.js";
4
+ import { SDKError, TransportError } from "../errors.js";
5
+ import { getStealthProfile } from "../stealth/profiles.js";
6
+ import { createProxyAuthIpDeniedError, createProxyEdgeAuthRejectedError, createProxyEdgeTlsRejectedError, createProxyPoolExhaustedError, createProxyPoolStaleError, isProxyAuthIpDeniedMessage, isProxyEdgeAuthRejectedMessage, isProxyEdgeTlsRejectedResponse, isProxyPoolRefreshableError, isProxyPoolStaleMessage, isProxyPoolStaleStatus, PROXY_EDGE_AUTH_REJECTED_CODE, PROXY_POOL_STALE_CODE, } from "./proxy-errors.js";
7
+ import { computeProxyAttemptIndex, computeProxyTransportRetryDelayMs, createDefaultProxyTransportRetryOptions, normalizeProxyTransportRetryOptions, shouldRetryProxyTransportAttempt, validateUnsafeProxyTransportRetryMethods, } from "./proxy-retry-policy.js";
8
+ import { appendQueryParams } from "./request-options.js";
9
9
  const DEFAULT_PROFILE = "chrome-146";
10
10
  const MISSING_PROXY_WARNING = "[provider-sdk] Provider requested proxy routing, but no proxy URL was configured. Continuing without proxy.";
11
- const MAX_POLICY_PROXY_RETRY_ATTEMPTS = SMARTPROXY_MAX_POOL_SIZE;
12
11
  const MAX_POLICY_PROXY_POOL_REFRESHES = 1;
13
12
  const PROXY_CONNECT_FAILURE_CODE = "proxy_connect_failed";
14
13
  const PROXY_CONNECT_FAILURE_BODY_PATTERN = /\bproxy\b.*\b(non[\s-]?200|connect|tunnel)|\bconnect\b.*\bproxy\b|\btunnel\b/i;
15
14
  const PROXY_AUTH_DIAGNOSTIC_URL = "http://example.com/";
16
15
  const PROXY_AUTH_DIAGNOSTIC_TIMEOUT_MS = 5_000;
17
- const DEFAULT_STEALTH_RETRY_METHODS = ["GET", "HEAD", "OPTIONS"];
18
- const DEFAULT_STEALTH_RETRY_ERROR_CODES = [
19
- PROXY_CONNECT_FAILURE_CODE,
20
- "transport_network_error",
21
- "transport_timeout",
22
- ];
23
- const RATE_LIMIT_STEALTH_RETRY_ERROR_CODES = ["transport_timeout"];
24
- const KNOWN_STEALTH_RETRY_METHODS = new Set([
25
- "GET",
26
- "HEAD",
27
- "POST",
28
- "PUT",
29
- "DELETE",
30
- "OPTIONS",
31
- "TRACE",
32
- "PATCH",
33
- ]);
34
- const UNSAFE_STEALTH_RETRY_METHODS = new Set([
35
- "POST",
36
- "PUT",
37
- "PATCH",
38
- "DELETE",
39
- "TRACE",
40
- ]);
41
- const MAX_STEALTH_RETRY_ATTEMPTS = 8;
16
+ const STEALTH_PROXY_TRANSPORT_RETRY_ERROR_CODES = [PROXY_CONNECT_FAILURE_CODE];
42
17
  const REMOVED_CHROME_PROFILE_NAMES = new Set([
43
18
  "chrome-120",
44
19
  "chrome-124",
@@ -303,130 +278,8 @@ function isPolicyManagedProxy(options) {
303
278
  const policy = options.proxyPolicy ?? options.upstream?.proxy;
304
279
  return Boolean(policy && typeof policy === "object");
305
280
  }
306
- function isRetrySafeStealthMethod(method) {
307
- return method === "GET" || method === "HEAD" || method === "OPTIONS";
308
- }
309
- function createStealthRetryOptions(preset) {
310
- switch (preset) {
311
- case HttpRetryPreset.Off:
312
- return {
313
- attempts: 1,
314
- methods: DEFAULT_STEALTH_RETRY_METHODS,
315
- errorCodes: DEFAULT_STEALTH_RETRY_ERROR_CODES,
316
- unsafeMethodPolicy: HttpRetryUnsafeMethodPolicy.Reject,
317
- };
318
- case HttpRetryPreset.AggressiveRead:
319
- return {
320
- attempts: 4,
321
- methods: DEFAULT_STEALTH_RETRY_METHODS,
322
- errorCodes: DEFAULT_STEALTH_RETRY_ERROR_CODES,
323
- unsafeMethodPolicy: HttpRetryUnsafeMethodPolicy.Reject,
324
- };
325
- case HttpRetryPreset.RateLimitAware:
326
- return {
327
- attempts: 3,
328
- methods: DEFAULT_STEALTH_RETRY_METHODS,
329
- errorCodes: RATE_LIMIT_STEALTH_RETRY_ERROR_CODES,
330
- unsafeMethodPolicy: HttpRetryUnsafeMethodPolicy.Reject,
331
- };
332
- case HttpRetryPreset.SafeRead:
333
- case HttpRetryPreset.TransportTransient:
334
- return {
335
- attempts: 3,
336
- methods: DEFAULT_STEALTH_RETRY_METHODS,
337
- errorCodes: DEFAULT_STEALTH_RETRY_ERROR_CODES,
338
- unsafeMethodPolicy: HttpRetryUnsafeMethodPolicy.Reject,
339
- };
340
- }
341
- throw new ProviderError(`Unknown stealth retry preset: ${preset}`, {
342
- code: "retry_invalid_policy",
343
- });
344
- }
345
- function normalizeStealthRetryOptions(retry) {
346
- if (retry === undefined)
347
- return undefined;
348
- if (retry === false)
349
- return createStealthRetryOptions(HttpRetryPreset.Off);
350
- if (retry === true)
351
- return createStealthRetryOptions(HttpRetryPreset.TransportTransient);
352
- if (typeof retry === "string") {
353
- if (!Object.values(HttpRetryPreset).includes(retry)) {
354
- throw new ProviderError(`Unknown stealth retry preset: ${retry}`, {
355
- code: "retry_invalid_policy",
356
- });
357
- }
358
- return createStealthRetryOptions(retry);
359
- }
360
- if (typeof retry !== "object" || retry === null || Array.isArray(retry)) {
361
- throw new ProviderError("Stealth retry policy must be a plain object", {
362
- code: "retry_invalid_policy",
363
- });
364
- }
365
- if (retry.unsafeMethodPolicy !== undefined &&
366
- !Object.values(HttpRetryUnsafeMethodPolicy).includes(retry.unsafeMethodPolicy)) {
367
- throw new ProviderError(`Unknown stealth retry unsafe method policy: ${String(retry.unsafeMethodPolicy)}`, { code: "retry_invalid_policy" });
368
- }
369
- if (retry.methods !== undefined) {
370
- if (!Array.isArray(retry.methods)) {
371
- throw new ProviderError("Stealth retry methods must be an array", {
372
- code: "retry_invalid_policy",
373
- });
374
- }
375
- const unknownMethods = retry.methods
376
- .map((method) => (typeof method === "string" ? method.toUpperCase() : ""))
377
- .filter((method) => !KNOWN_STEALTH_RETRY_METHODS.has(method));
378
- if (unknownMethods.length > 0) {
379
- throw new ProviderError(`Unknown stealth retry method(s): ${unknownMethods.join(", ")}`, { code: "retry_invalid_policy" });
380
- }
381
- }
382
- if (retry.errorCodes !== undefined) {
383
- if (!Array.isArray(retry.errorCodes) ||
384
- retry.errorCodes.some((errorCode) => typeof errorCode !== "string")) {
385
- throw new ProviderError("Stealth retry errorCodes must contain only strings", { code: "retry_invalid_policy" });
386
- }
387
- }
388
- const base = createStealthRetryOptions(retry.preset ?? HttpRetryPreset.TransportTransient);
389
- const attempts = retry.attempts === undefined || !Number.isFinite(retry.attempts)
390
- ? base.attempts
391
- : Math.max(1, Math.min(MAX_STEALTH_RETRY_ATTEMPTS, Math.floor(retry.attempts)));
392
- const normalized = {
393
- attempts,
394
- methods: retry.methods?.map((method) => method.toUpperCase()) ?? base.methods,
395
- errorCodes: retry.errorCodes ?? base.errorCodes,
396
- unsafeMethodPolicy: retry.unsafeMethodPolicy ?? base.unsafeMethodPolicy,
397
- };
398
- if (normalized.unsafeMethodPolicy !==
399
- HttpRetryUnsafeMethodPolicy.AllowExplicitUnsafe) {
400
- const unsafeMethods = normalized.methods.filter((method) => UNSAFE_STEALTH_RETRY_METHODS.has(method.toUpperCase()));
401
- if (unsafeMethods.length > 0) {
402
- throw new ProviderError(`Stealth retry methods include unsafe method(s): ${unsafeMethods.join(", ")}`, { code: "retry_unsafe_method" });
403
- }
404
- }
405
- return normalized;
406
- }
407
- function isExplicitStealthRetryAllowed(method, error, retryOptions) {
408
- if (!retryOptions || retryOptions.attempts <= 1)
409
- return false;
410
- return (retryOptions.methods.includes(method.toUpperCase()) &&
411
- retryOptions.errorCodes.includes(proxyAttemptErrorCode(error)));
412
- }
413
- function isRetryableProxyTransportError(error) {
414
- if (error instanceof TransportError) {
415
- if (error.code === PROXY_AUTH_IP_DENIED_CODE) {
416
- return false;
417
- }
418
- return (error.code === PROXY_CONNECT_FAILURE_CODE ||
419
- error.code === "transport_network_error" ||
420
- error.code === "transport_timeout");
421
- }
422
- if (error instanceof SDKError) {
423
- return false;
424
- }
425
- const message = error instanceof Error ? error.message : String(error);
426
- return /\bproxy\b|\bnon[\s-]?200\b|\bconnect\b|\btunnel\b/i.test(message);
427
- }
428
281
  function isProxyConnectFailureResponse(response, body) {
429
- return (response.status === 0 && PROXY_CONNECT_FAILURE_BODY_PATTERN.test(body ?? ""));
282
+ return response.status === 0 && PROXY_CONNECT_FAILURE_BODY_PATTERN.test(body ?? "");
430
283
  }
431
284
  function createProxyConnectFailureError(body, cause) {
432
285
  const bodyExcerpt = (body ?? "").trim().slice(0, 1_000);
@@ -529,8 +382,7 @@ function normalizeStealthTransportError(error) {
529
382
  return createProxyEdgeAuthRejectedError(error instanceof Error ? error : undefined);
530
383
  }
531
384
  const proxyTunnelStatus = getProxyTunnelStatus(error);
532
- if (proxyTunnelStatus !== undefined &&
533
- isProxyPoolStaleStatus(proxyTunnelStatus)) {
385
+ if (proxyTunnelStatus !== undefined && isProxyPoolStaleStatus(proxyTunnelStatus)) {
534
386
  return createProxyPoolStaleError(proxyTunnelStatus, error instanceof Error ? error : undefined);
535
387
  }
536
388
  if (PROXY_CONNECT_FAILURE_BODY_PATTERN.test(message)) {
@@ -542,6 +394,9 @@ function normalizeStealthTransportError(error) {
542
394
  cause: error instanceof Error ? error : undefined,
543
395
  });
544
396
  }
397
+ function sleep(ms) {
398
+ return new Promise((resolve) => setTimeout(resolve, ms));
399
+ }
545
400
  function normalizeMethod(method) {
546
401
  switch (method.toUpperCase()) {
547
402
  case "HEAD":
@@ -607,19 +462,21 @@ function createSessionFetcher(baseUrl, defaultProfile, clientOptions) {
607
462
  }
608
463
  return client;
609
464
  }
610
- async function resolveRequestProxy(options, proxyAttempt) {
611
- const rawProxyAttemptOffset = options?.proxyAttemptOffset ?? 0;
612
- const proxyAttemptOffset = Number.isFinite(rawProxyAttemptOffset)
613
- ? Math.max(0, Math.floor(rawProxyAttemptOffset))
614
- : 0;
465
+ async function resolveRequestProxy(options, proxyAttempt, refreshEpoch) {
615
466
  const resolvedProxy = await resolveProxyConfigAsync({
616
467
  proxy: options?.proxy ?? clientOptions.proxy,
617
468
  upstream: clientOptions.upstream,
618
469
  apifuseConfig: clientOptions.apifuseConfig,
619
470
  affinityKey: clientOptions.affinityKey,
620
- proxyAttempt: proxyAttempt === undefined
621
- ? proxyAttemptOffset
622
- : proxyAttemptOffset + proxyAttempt,
471
+ proxyAttempt: computeProxyAttemptIndex({
472
+ baseProxyAttempt: clientOptions.proxyAttempt,
473
+ proxyAttemptOffset: options?.proxyAttemptOffset,
474
+ retryAttemptOffset: proxyAttempt,
475
+ }),
476
+ // The impit stealth transport tunnels both HTTP CONNECT and SOCKS5,
477
+ // preserving the client TLS fingerprint end-to-end.
478
+ transportProtocols: ["http", "socks5"],
479
+ ...(refreshEpoch === undefined ? {} : { proxyRefreshEpoch: refreshEpoch }),
623
480
  telemetry: clientOptions.telemetry,
624
481
  });
625
482
  if (resolvedProxy.shouldWarn && !hasWarnedMissingProxy) {
@@ -630,22 +487,51 @@ function createSessionFetcher(baseUrl, defaultProfile, clientOptions) {
630
487
  url: resolvedProxy.url,
631
488
  poolIndex: proxyPoolIndexFromDiagnostics(resolvedProxy.diagnostics),
632
489
  proxyHash: proxyEndpointHash(resolvedProxy.url),
490
+ vendor: vendorFromResolvedSource(resolvedProxy.source),
633
491
  };
634
492
  }
635
493
  const session = {
636
494
  async fetch(url, options = {}) {
637
495
  const method = normalizeMethod(options.method ?? "GET");
638
496
  const hasExplicitRetryPolicy = options.retry !== undefined;
639
- const stealthRetryOptions = normalizeStealthRetryOptions(options.retry);
497
+ const stealthRetryOptions = normalizeProxyTransportRetryOptions(options.retry, {
498
+ extraErrorCodes: STEALTH_PROXY_TRANSPORT_RETRY_ERROR_CODES,
499
+ label: "Stealth",
500
+ }) ??
501
+ (hasExplicitRetryPolicy
502
+ ? undefined
503
+ : createDefaultProxyTransportRetryOptions({
504
+ extraErrorCodes: STEALTH_PROXY_TRANSPORT_RETRY_ERROR_CODES,
505
+ label: "Stealth",
506
+ }));
507
+ if (stealthRetryOptions) {
508
+ validateUnsafeProxyTransportRetryMethods(stealthRetryOptions, "Stealth");
509
+ }
640
510
  const hasPolicyProxy = isPolicyManagedProxy(clientOptions);
641
511
  const usesPolicyAllocator = hasPolicyProxy && !options.proxy && !clientOptions.proxy;
642
- const maxAttempts = usesPolicyAllocator
643
- ? Math.max(1, Math.min(MAX_POLICY_PROXY_RETRY_ATTEMPTS, clientOptions.proxyPolicy?.session?.poolSize ??
644
- (typeof clientOptions.upstream?.proxy === "object"
645
- ? clientOptions.upstream.proxy.session?.poolSize
646
- : undefined) ??
647
- DEFAULT_SMARTPROXY_POOL_SIZE))
648
- : 1;
512
+ const retryAttemptCap = Math.max(1, stealthRetryOptions?.attempts ?? 1);
513
+ // Span the whole vendor chain: successive attempts rotate one vendor's
514
+ // pool, then fail over to the next vendor via the flat attempt index.
515
+ const policyProxy = clientOptions.proxyPolicy ??
516
+ (typeof clientOptions.upstream?.proxy === "object"
517
+ ? clientOptions.upstream.proxy
518
+ : undefined);
519
+ // The pool span is already bounded by each vendor's max pool size
520
+ // (smartproxy ≤20, nodemaven ≤50), so the configured span never exceeds
521
+ // the chain's true maximum — a large NodeMaven pool stays fully
522
+ // reachable rather than being truncated at an arbitrary ceiling.
523
+ const policyProxyAttemptCap = Math.max(1, policyProxy ? resolvePolicyProxyPoolSpan(policyProxy) : DEFAULT_SMARTPROXY_POOL_SIZE);
524
+ // A registry vendor chain (smartproxy/nodemaven) is the only policy whose
525
+ // successive attempts resolve a *different* endpoint, so it is the only one
526
+ // that may widen the attempt cap to the pool span, de-duplicate endpoints,
527
+ // and drive allocator stale-pool refresh. A static custom/decodo policy
528
+ // resolves the same URL every attempt: widening/refreshing it would resend
529
+ // the request dozens of times (up to maxAttempts × refreshes) and bypass
530
+ // retry:false and unsafe-method controls. Static policies therefore follow
531
+ // the ordinary transport-retry budget instead.
532
+ const rotatesRegistryChain = usesPolicyAllocator && policyResolvesRegistryVendorChain(policyProxy);
533
+ const maxAttempts = rotatesRegistryChain ? policyProxyAttemptCap : retryAttemptCap;
534
+ const dedupeAllocatorEndpoints = rotatesRegistryChain;
649
535
  let lastError;
650
536
  for (let refreshAttempt = 0; refreshAttempt <= MAX_POLICY_PROXY_POOL_REFRESHES; refreshAttempt += 1) {
651
537
  let stalePoolError;
@@ -661,14 +547,12 @@ function createSessionFetcher(baseUrl, defaultProfile, clientOptions) {
661
547
  return;
662
548
  attemptRecorded = true;
663
549
  clientOptions.telemetry?.recordProxyAttempt?.({
664
- provider: "smartproxy",
550
+ provider: attemptProxy?.vendor ?? "smartproxy",
665
551
  attempt: attempt + 1,
666
552
  ...(attemptProxy?.poolIndex === undefined
667
553
  ? {}
668
554
  : { poolIndex: attemptProxy.poolIndex }),
669
- ...(attemptProxy?.proxyHash
670
- ? { proxyHash: attemptProxy.proxyHash }
671
- : {}),
555
+ ...(attemptProxy?.proxyHash ? { proxyHash: attemptProxy.proxyHash } : {}),
672
556
  outcome,
673
557
  ...(errorCode ? { errorCode } : {}),
674
558
  ...(status === undefined ? {} : { status }),
@@ -677,18 +561,21 @@ function createSessionFetcher(baseUrl, defaultProfile, clientOptions) {
677
561
  };
678
562
  try {
679
563
  assertNoUnsupportedFingerprintOverrides(options);
680
- attemptProxy = await resolveRequestProxy(options, attempt);
564
+ attemptProxy = await resolveRequestProxy(options, attempt, refreshAttempt);
681
565
  proxy = attemptProxy.url;
682
- if (proxy) {
566
+ if (proxy && dedupeAllocatorEndpoints) {
567
+ // An under-filled allocation repeats endpoints (via the modulo
568
+ // pool mapping) before the flat offset crosses into the next
569
+ // vendor. Skip an already-tried endpoint and advance the offset
570
+ // rather than breaking — breaking here would strand the request on
571
+ // the primary vendor and never reach the fallback leg.
683
572
  if (attemptedProxies.has(proxy)) {
684
- break;
573
+ continue;
685
574
  }
686
575
  attemptedProxies.add(proxy);
687
576
  }
688
577
  const ignoreTlsErrors = Boolean(options.stealth?.insecureSkipVerify ??
689
- (!hasPolicyProxy &&
690
- proxy &&
691
- clientOptions.proxyStealth?.insecureSkipVerify));
578
+ (!hasPolicyProxy && proxy && clientOptions.proxyStealth?.insecureSkipVerify));
692
579
  const profileName = options.profile ?? defaultProfile;
693
580
  const requestUrl = appendQueryParams(resolveUrl(baseUrl, url), options.params);
694
581
  const headers = { ...(options.headers ?? {}) };
@@ -709,17 +596,13 @@ function createSessionFetcher(baseUrl, defaultProfile, clientOptions) {
709
596
  const response = await getClient(profileName, proxy, ignoreTlsErrors).fetch(requestUrl, requestInit);
710
597
  const normalized = await normalizeResponse(response, requestUrl);
711
598
  cookieJar.setFromCookieStrings(setCookieHeadersFromResponse(response.headers));
712
- if (proxy &&
713
- isProxyConnectFailureResponse(response, normalized.body)) {
599
+ if (proxy && isProxyConnectFailureResponse(response, normalized.body)) {
714
600
  throw createProxyConnectFailureError(normalized.body);
715
601
  }
716
602
  if (response.status >= 400) {
717
603
  if (proxy &&
718
604
  usesPolicyAllocator &&
719
- isProxyEdgeTlsRejectedResponse(response.status, [
720
- JSON.stringify(responseHeadersToRecord(response.headers)),
721
- normalized.body,
722
- ].join("\n"))) {
605
+ isProxyEdgeTlsRejectedResponse(response.status, [JSON.stringify(responseHeadersToRecord(response.headers)), normalized.body].join("\n"))) {
723
606
  throw createProxyEdgeTlsRejectedError(response.status);
724
607
  }
725
608
  if (proxy && isProxyAuthIpDeniedMessage(normalized.body)) {
@@ -747,9 +630,7 @@ function createSessionFetcher(baseUrl, defaultProfile, clientOptions) {
747
630
  const normalizedError = normalizeStealthTransportError(error);
748
631
  recordProxyAttempt("error", proxyAttemptErrorCode(normalizedError), proxyAttemptStatus(normalizedError));
749
632
  lastError = normalizedError;
750
- if (proxy &&
751
- usesPolicyAllocator &&
752
- isProxyPoolRefreshableError(normalizedError)) {
633
+ if (proxy && rotatesRegistryChain && isProxyPoolRefreshableError(normalizedError)) {
753
634
  stalePoolError = normalizedError;
754
635
  if (shouldRunProxyAuthDiagnostic(normalizedError)) {
755
636
  stalePoolDiagnosticProxy = proxy;
@@ -759,21 +640,43 @@ function createSessionFetcher(baseUrl, defaultProfile, clientOptions) {
759
640
  }
760
641
  break;
761
642
  }
762
- if (proxy &&
763
- attempt + 1 <
764
- (stealthRetryOptions
765
- ? Math.min(maxAttempts, stealthRetryOptions.attempts)
766
- : maxAttempts) &&
767
- (!hasExplicitRetryPolicy
768
- ? isRetrySafeStealthMethod(method)
769
- : isExplicitStealthRetryAllowed(method, normalizedError, stealthRetryOptions)) &&
770
- isRetryableProxyTransportError(normalizedError)) {
643
+ // Cap the number of transport retries. For a policy-allocator chain,
644
+ // every attempt resolves a *different* endpoint/vendor (poolIndex
645
+ // rotates across the concatenated vendor pool spans), so a transport
646
+ // failure is a signal to advance to the next endpoint — potentially
647
+ // crossing into the fallback vendor — not to retry the same endpoint.
648
+ // Truncating that rotation at the per-endpoint retry budget would
649
+ // strand the request on the primary vendor and never reach the
650
+ // fallback, since the crossover only happens once the flat attempt
651
+ // index exceeds the primary vendor's pool size (~10-20).
652
+ // resolvePolicyTransportAttemptCap widens to the full chain span only
653
+ // for implicit, safe-method allocator requests; explicit retry
654
+ // policies (their documented `attempts` ceiling), unsafe methods, and
655
+ // static/non-registry vendors keep the per-endpoint retry budget.
656
+ const transportRetryCap = resolvePolicyTransportAttemptCap({
657
+ policy: policyProxy,
658
+ usesPolicyAllocator,
659
+ retryAttempts: stealthRetryOptions?.attempts ?? 1,
660
+ explicitRetry: hasExplicitRetryPolicy,
661
+ method,
662
+ });
663
+ if (attempt + 1 < transportRetryCap &&
664
+ shouldRetryProxyTransportAttempt({
665
+ error: normalizedError,
666
+ explicitRetry: hasExplicitRetryPolicy,
667
+ method,
668
+ options: stealthRetryOptions,
669
+ proxyUsed: Boolean(proxy),
670
+ })) {
671
+ if (stealthRetryOptions) {
672
+ await sleep(computeProxyTransportRetryDelayMs(stealthRetryOptions, attempt + 1));
673
+ }
771
674
  continue;
772
675
  }
773
676
  throw normalizedError;
774
677
  }
775
678
  }
776
- if (usesPolicyAllocator &&
679
+ if (rotatesRegistryChain &&
777
680
  stalePoolError &&
778
681
  refreshAttempt < MAX_POLICY_PROXY_POOL_REFRESHES) {
779
682
  await invalidateProxyResolutionCacheAsync({
@@ -920,10 +823,7 @@ function createSessionFetcher(baseUrl, defaultProfile, clientOptions) {
920
823
  }
921
824
  catch (error) {
922
825
  const message = error instanceof Error
923
- ? [
924
- error.message,
925
- error.cause instanceof Error ? error.cause.message : "",
926
- ]
826
+ ? [error.message, error.cause instanceof Error ? error.cause.message : ""]
927
827
  .filter(Boolean)
928
828
  .join(" ")
929
829
  : String(error);
@@ -951,12 +851,8 @@ function hasHeader(headers, name) {
951
851
  return Object.keys(headers).some((key) => key.toLowerCase() === needle);
952
852
  }
953
853
  export function createStealthClient(baseUrl, defaultProfileOrOptions = DEFAULT_PROFILE, clientOptions = {}) {
954
- const defaultProfile = typeof defaultProfileOrOptions === "string"
955
- ? defaultProfileOrOptions
956
- : DEFAULT_PROFILE;
957
- const resolvedClientOptions = typeof defaultProfileOrOptions === "string"
958
- ? clientOptions
959
- : defaultProfileOrOptions;
854
+ const defaultProfile = typeof defaultProfileOrOptions === "string" ? defaultProfileOrOptions : DEFAULT_PROFILE;
855
+ const resolvedClientOptions = typeof defaultProfileOrOptions === "string" ? clientOptions : defaultProfileOrOptions;
960
856
  let sharedSession = null;
961
857
  function getSharedSession() {
962
858
  if (!sharedSession) {
@@ -1,4 +1,4 @@
1
- import type { ProviderSttConfig, SttContext, SttTranscribeRequest, SttVerificationCodeOptions, VerificationCodeExtractionResult } from "../types";
1
+ import type { ProviderSttConfig, SttContext, SttTranscribeRequest, SttVerificationCodeOptions, VerificationCodeExtractionResult } from "../types.js";
2
2
  export declare const APIFUSE__STT__BACKEND_ENV = "APIFUSE__STT__BACKEND";
3
3
  export declare const APIFUSE__STT__MODEL_ENV = "APIFUSE__STT__MODEL";
4
4
  export declare const CLOUDFLARE_ACCOUNT_ID_ENV = "APIFUSE__CLOUDFLARE__ACCOUNT_ID";
@@ -1,4 +1,4 @@
1
- import { ProviderError, TransportError, ValidationError } from "../errors";
1
+ import { ProviderError, TransportError, ValidationError } from "../errors.js";
2
2
  export const APIFUSE__STT__BACKEND_ENV = "APIFUSE__STT__BACKEND";
3
3
  export const APIFUSE__STT__MODEL_ENV = "APIFUSE__STT__MODEL";
4
4
  export const CLOUDFLARE_ACCOUNT_ID_ENV = "APIFUSE__CLOUDFLARE__ACCOUNT_ID";
@@ -59,17 +59,12 @@ export function createSttClientFromEnv(config, env = process.env) {
59
59
  return createCloudflareWorkersAiSttClient({
60
60
  accountId,
61
61
  apiToken,
62
- model: normalizedEnvValue(env, APIFUSE__STT__MODEL_ENV) ??
63
- DEFAULT_CLOUDFLARE_WORKERS_AI_STT_MODEL,
62
+ model: normalizedEnvValue(env, APIFUSE__STT__MODEL_ENV) ?? DEFAULT_CLOUDFLARE_WORKERS_AI_STT_MODEL,
64
63
  });
65
64
  }
66
65
  function base64ByteLength(data) {
67
66
  const normalized = data.trim();
68
- const padding = normalized.endsWith("==")
69
- ? 2
70
- : normalized.endsWith("=")
71
- ? 1
72
- : 0;
67
+ const padding = normalized.endsWith("==") ? 2 : normalized.endsWith("=") ? 1 : 0;
73
68
  return Math.floor((normalized.length * 3) / 4) - padding;
74
69
  }
75
70
  function assertBase64Audio(audio, maxAudioBytes) {
@@ -80,9 +75,7 @@ function assertBase64Audio(audio, maxAudioBytes) {
80
75
  });
81
76
  }
82
77
  const data = audio.data.trim();
83
- if (data.length === 0 ||
84
- data.length % 4 !== 0 ||
85
- !BASE64_AUDIO_PATTERN.test(data)) {
78
+ if (data.length === 0 || data.length % 4 !== 0 || !BASE64_AUDIO_PATTERN.test(data)) {
86
79
  throw new ValidationError("STT audio.data must be a base64-encoded string", {
87
80
  code: "INVALID_STT_AUDIO",
88
81
  });
@@ -90,7 +83,9 @@ function assertBase64Audio(audio, maxAudioBytes) {
90
83
  const bytes = base64ByteLength(data);
91
84
  const maxBytes = maxAudioBytes ?? DEFAULT_STT_MAX_AUDIO_BYTES;
92
85
  if (bytes > maxBytes) {
93
- throw new ValidationError(`STT audio exceeds maxAudioBytes (${bytes} > ${maxBytes})`, { code: "STT_AUDIO_TOO_LARGE" });
86
+ throw new ValidationError(`STT audio exceeds maxAudioBytes (${bytes} > ${maxBytes})`, {
87
+ code: "STT_AUDIO_TOO_LARGE",
88
+ });
94
89
  }
95
90
  return bytes;
96
91
  }
@@ -227,8 +222,7 @@ export function createCloudflareWorkersAiSttClient(options) {
227
222
  return {
228
223
  async transcribe(request) {
229
224
  const warnings = [];
230
- if (request.initialPrompt &&
231
- effectivePromptPolicy(request) !== "custom-hint") {
225
+ if (request.initialPrompt && effectivePromptPolicy(request) !== "custom-hint") {
232
226
  const warning = warnOrThrowUnsupportedOption(request, "initialPrompt is honored only when promptPolicy is custom-hint");
233
227
  if (warning)
234
228
  warnings.push(warning);
@@ -350,7 +344,9 @@ function lengthSet(codeLengths) {
350
344
  }
351
345
  function validCodeLength(value) {
352
346
  if (!Number.isInteger(value) || value < 1 || value > 32) {
353
- throw new ValidationError("STT verification code length must be an integer between 1 and 32", { code: "INVALID_STT_VERIFICATION_CODE_OPTIONS" });
347
+ throw new ValidationError("STT verification code length must be an integer between 1 and 32", {
348
+ code: "INVALID_STT_VERIFICATION_CODE_OPTIONS",
349
+ });
354
350
  }
355
351
  return value;
356
352
  }
@@ -1,5 +1,5 @@
1
- import type { TraceContext as BaseTraceContext, TraceAttributeValue, TraceConfig, TraceSpan } from "../types";
2
- import { type OTLPExportOptions } from "./otlp";
1
+ import type { TraceContext as BaseTraceContext, TraceAttributeValue, TraceConfig, TraceSpan } from "../types.js";
2
+ import { type OTLPExportOptions } from "./otlp.js";
3
3
  export type SpanAttributeValue = TraceAttributeValue;
4
4
  export type Span = TraceSpan;
5
5
  export interface TraceContext extends BaseTraceContext {
@@ -1,5 +1,5 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
- import { exportSpansOTLP } from "./otlp";
2
+ import { exportSpansOTLP } from "./otlp.js";
3
3
  export const TRACE_RECORDER = Symbol.for("@apifuse/provider-sdk/runtime/trace-recorder");
4
4
  function buildOTLPExportOptions(config) {
5
5
  if (config?.exporter !== "otlp") {
@@ -23,9 +23,7 @@ export function resolveTraceContextOptions(config) {
23
23
  };
24
24
  }
25
25
  function normalizeAttributeValue(value) {
26
- if (typeof value === "string" ||
27
- typeof value === "number" ||
28
- typeof value === "boolean") {
26
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
29
27
  return value;
30
28
  }
31
29
  if (value === null || value === undefined) {
@@ -1,4 +1,4 @@
1
- import type { Span } from "./trace";
1
+ import type { Span } from "./trace.js";
2
2
  export type WaterfallRequest = {
3
3
  method: string;
4
4
  path: string;
package/dist/schema.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type ZodString, type ZodType, z } from "zod";
2
- import type { InferSchemaOutput, ProviderLocaleKey, SchemaLike } from "./types";
2
+ import type { InferSchemaOutput, ProviderLocaleKey, SchemaLike } from "./types.js";
3
3
  export { z };
4
4
  export type SchemaValidationResult<TSchema extends SchemaLike> = {
5
5
  success: true;