@apifuse/provider-sdk 2.2.0-beta.3 → 2.2.0-beta.5

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 (165) hide show
  1. package/AUTHORING.md +53 -0
  2. package/CHANGELOG.md +8 -0
  3. package/bin/apifuse-check.ts +18 -58
  4. package/bin/apifuse-create.ts +1 -1
  5. package/bin/apifuse-dev.ts +27 -52
  6. package/bin/apifuse-pack-smoke.ts +22 -81
  7. package/bin/apifuse-pack-types.ts +266 -0
  8. package/bin/apifuse-perf.ts +45 -127
  9. package/bin/apifuse-record.ts +23 -61
  10. package/bin/apifuse-submit-check.ts +266 -34
  11. package/bin/apifuse.ts +1 -1
  12. package/bin/submit-check-xml.ts +1 -1
  13. package/dist/auth-turn/index.d.ts +1 -1
  14. package/dist/auth.d.ts +2 -2
  15. package/dist/auth.js +9 -18
  16. package/dist/ceremonies/index.d.ts +1 -1
  17. package/dist/ceremonies/index.js +8 -18
  18. package/dist/config/loader.d.ts +2 -2
  19. package/dist/config/loader.js +19 -42
  20. package/dist/contract-serialization.d.ts +2 -2
  21. package/dist/contract-serialization.js +3 -6
  22. package/dist/contract-types.d.ts +2 -2
  23. package/dist/contract.d.ts +3 -3
  24. package/dist/contract.js +4 -6
  25. package/dist/define.d.ts +8 -1
  26. package/dist/define.js +57 -115
  27. package/dist/dev.d.ts +1 -1
  28. package/dist/dev.js +1 -1
  29. package/dist/errors.d.ts +1 -1
  30. package/dist/errors.js +1 -3
  31. package/dist/i18n/catalog.d.ts +2 -2
  32. package/dist/i18n/catalog.js +4 -10
  33. package/dist/i18n/index.d.ts +2 -2
  34. package/dist/i18n/index.js +2 -2
  35. package/dist/i18n/keys.d.ts +2 -2
  36. package/dist/index.d.ts +43 -42
  37. package/dist/index.js +38 -37
  38. package/dist/lint.js +8 -15
  39. package/dist/provider.d.ts +11 -11
  40. package/dist/provider.js +9 -9
  41. package/dist/public-schema-field-lint.d.ts +1 -1
  42. package/dist/recipes/gov-api.js +1 -1
  43. package/dist/runtime/auth-flow.d.ts +1 -1
  44. package/dist/runtime/auth-flow.js +3 -3
  45. package/dist/runtime/browser.d.ts +1 -1
  46. package/dist/runtime/browser.js +15 -29
  47. package/dist/runtime/cache.d.ts +1 -1
  48. package/dist/runtime/cache.js +4 -8
  49. package/dist/runtime/choice.d.ts +1 -1
  50. package/dist/runtime/choice.js +12 -34
  51. package/dist/runtime/credential.d.ts +1 -1
  52. package/dist/runtime/credential.js +1 -1
  53. package/dist/runtime/env.d.ts +1 -1
  54. package/dist/runtime/executor.d.ts +1 -1
  55. package/dist/runtime/executor.js +2 -2
  56. package/dist/runtime/http.d.ts +2 -2
  57. package/dist/runtime/http.js +5 -5
  58. package/dist/runtime/insights.d.ts +1 -1
  59. package/dist/runtime/insights.js +6 -13
  60. package/dist/runtime/instrumentation.d.ts +2 -2
  61. package/dist/runtime/instrumentation.js +5 -15
  62. package/dist/runtime/keyring.js +1 -1
  63. package/dist/runtime/namespace.js +1 -1
  64. package/dist/runtime/otlp.d.ts +1 -1
  65. package/dist/runtime/perf.d.ts +1 -1
  66. package/dist/runtime/provider.d.ts +1 -1
  67. package/dist/runtime/provider.js +1 -2
  68. package/dist/runtime/proxy-errors.d.ts +1 -1
  69. package/dist/runtime/proxy-errors.js +3 -5
  70. package/dist/runtime/proxy-retry-policy.d.ts +2 -2
  71. package/dist/runtime/proxy-retry-policy.js +2 -2
  72. package/dist/runtime/proxy-telemetry.d.ts +1 -1
  73. package/dist/runtime/proxy-telemetry.js +16 -48
  74. package/dist/runtime/redis.d.ts +1 -1
  75. package/dist/runtime/redis.js +2 -4
  76. package/dist/runtime/request-options.d.ts +1 -1
  77. package/dist/runtime/state.d.ts +2 -2
  78. package/dist/runtime/state.js +3 -3
  79. package/dist/runtime/stealth.d.ts +2 -2
  80. package/dist/runtime/stealth.js +6 -6
  81. package/dist/runtime/stt.d.ts +1 -1
  82. package/dist/runtime/stt.js +11 -15
  83. package/dist/runtime/trace.d.ts +2 -2
  84. package/dist/runtime/trace.js +2 -4
  85. package/dist/runtime/waterfall.d.ts +1 -1
  86. package/dist/schema.d.ts +1 -1
  87. package/dist/schema.js +7 -15
  88. package/dist/serve.d.ts +1 -1
  89. package/dist/serve.js +1 -1
  90. package/dist/server/index.d.ts +7 -7
  91. package/dist/server/index.js +6 -6
  92. package/dist/server/self-test-redaction.d.ts +1 -1
  93. package/dist/server/self-test-redaction.js +1 -1
  94. package/dist/server/self-test.d.ts +104 -3
  95. package/dist/server/self-test.js +673 -115
  96. package/dist/server/serve.d.ts +3 -3
  97. package/dist/server/serve.js +37 -49
  98. package/dist/server/types.js +2 -7
  99. package/dist/stealth/profiles.d.ts +1 -1
  100. package/dist/stealth/profiles.js +5 -14
  101. package/dist/stream.d.ts +1 -1
  102. package/dist/testing/index.d.ts +2 -2
  103. package/dist/testing/index.js +2 -2
  104. package/dist/testing/run.d.ts +1 -1
  105. package/dist/testing/run.js +7 -14
  106. package/dist/types.d.ts +57 -0
  107. package/dist/user-input.d.ts +30 -0
  108. package/dist/user-input.js +66 -0
  109. package/package.json +6 -4
  110. package/src/auth-turn/index.ts +1 -1
  111. package/src/auth.ts +28 -86
  112. package/src/ceremonies/index.ts +24 -78
  113. package/src/config/loader.ts +58 -176
  114. package/src/contract-serialization.ts +5 -11
  115. package/src/contract-types.ts +2 -2
  116. package/src/contract.ts +12 -28
  117. package/src/define.ts +174 -495
  118. package/src/dev.ts +4 -9
  119. package/src/errors.ts +4 -11
  120. package/src/i18n/catalog.ts +10 -32
  121. package/src/i18n/index.ts +2 -2
  122. package/src/i18n/keys.ts +5 -11
  123. package/src/index.ts +44 -42
  124. package/src/lint.ts +89 -159
  125. package/src/provider.ts +12 -11
  126. package/src/public-schema-field-lint.ts +7 -33
  127. package/src/recipes/gov-api.ts +2 -5
  128. package/src/runtime/auth-flow.ts +5 -7
  129. package/src/runtime/browser.ts +64 -187
  130. package/src/runtime/cache.ts +20 -67
  131. package/src/runtime/choice.ts +55 -129
  132. package/src/runtime/credential.ts +2 -2
  133. package/src/runtime/env.ts +1 -1
  134. package/src/runtime/executor.ts +9 -19
  135. package/src/runtime/http.ts +7 -7
  136. package/src/runtime/insights.ts +15 -53
  137. package/src/runtime/instrumentation.ts +19 -58
  138. package/src/runtime/keyring.ts +7 -19
  139. package/src/runtime/namespace.ts +2 -7
  140. package/src/runtime/otlp.ts +12 -23
  141. package/src/runtime/perf.ts +1 -1
  142. package/src/runtime/provider.ts +4 -9
  143. package/src/runtime/proxy-errors.ts +17 -38
  144. package/src/runtime/proxy-retry-policy.ts +3 -3
  145. package/src/runtime/proxy-telemetry.ts +23 -72
  146. package/src/runtime/redis.ts +4 -12
  147. package/src/runtime/request-options.ts +4 -13
  148. package/src/runtime/state.ts +30 -109
  149. package/src/runtime/stealth.ts +8 -8
  150. package/src/runtime/stt.ts +38 -94
  151. package/src/runtime/trace.ts +14 -44
  152. package/src/runtime/waterfall.ts +5 -18
  153. package/src/schema.ts +23 -84
  154. package/src/serve.ts +1 -1
  155. package/src/server/index.ts +12 -7
  156. package/src/server/self-test-redaction.ts +2 -2
  157. package/src/server/self-test.ts +857 -132
  158. package/src/server/serve.ts +89 -238
  159. package/src/server/types.ts +6 -19
  160. package/src/stealth/profiles.ts +10 -26
  161. package/src/stream.ts +8 -19
  162. package/src/testing/index.ts +2 -2
  163. package/src/testing/run.ts +19 -67
  164. package/src/types.ts +58 -0
  165. package/src/user-input.ts +118 -0
@@ -4,7 +4,7 @@ import type {
4
4
  ProxyResolutionTelemetryEvent,
5
5
  ProxyTelemetrySink,
6
6
  SmartproxyAllocatorBodyClass,
7
- } from "../config/loader";
7
+ } from "../config/loader.js";
8
8
 
9
9
  export const PROVIDER_TELEMETRY_HEADER = "X-ApiFuse-Provider-Telemetry";
10
10
 
@@ -55,31 +55,18 @@ const CACHE_STATUS_SEVERITY: Record<ProxyCacheStatus, number> = {
55
55
  allocator: 7,
56
56
  };
57
57
 
58
- function sumOptional(
59
- left: number | undefined,
60
- right: number | undefined,
61
- ): number | undefined {
58
+ function sumOptional(left: number | undefined, right: number | undefined): number | undefined {
62
59
  const total = (left ?? 0) + (right ?? 0);
63
60
  return total > 0 ? total : undefined;
64
61
  }
65
62
 
66
- function maxOptional(
67
- left: number | undefined,
68
- right: number | undefined,
69
- ): number | undefined {
70
- const values = [left, right].filter(
71
- (value): value is number => typeof value === "number",
72
- );
63
+ function maxOptional(left: number | undefined, right: number | undefined): number | undefined {
64
+ const values = [left, right].filter((value): value is number => typeof value === "number");
73
65
  return values.length > 0 ? Math.max(...values) : undefined;
74
66
  }
75
67
 
76
- function worseStatus(
77
- left: ProxyCacheStatus,
78
- right: ProxyCacheStatus,
79
- ): ProxyCacheStatus {
80
- return CACHE_STATUS_SEVERITY[right] > CACHE_STATUS_SEVERITY[left]
81
- ? right
82
- : left;
68
+ function worseStatus(left: ProxyCacheStatus, right: ProxyCacheStatus): ProxyCacheStatus {
69
+ return CACHE_STATUS_SEVERITY[right] > CACHE_STATUS_SEVERITY[left] ? right : left;
83
70
  }
84
71
 
85
72
  function encodeBase64Url(value: string): string {
@@ -97,9 +84,7 @@ export class ProxyTelemetryCollector implements ProxyTelemetrySink {
97
84
  cacheHit: event.cacheHit,
98
85
  resolutionMs: Math.max(0, Math.floor(event.resolutionMs)),
99
86
  allocatorMs:
100
- event.allocatorMs === undefined
101
- ? undefined
102
- : Math.max(0, Math.floor(event.allocatorMs)),
87
+ event.allocatorMs === undefined ? undefined : Math.max(0, Math.floor(event.allocatorMs)),
103
88
  allocatorStatus:
104
89
  event.allocatorStatus === undefined
105
90
  ? undefined
@@ -110,30 +95,20 @@ export class ProxyTelemetryCollector implements ProxyTelemetrySink {
110
95
  ? undefined
111
96
  : Math.max(1, Math.floor(event.allocatorAttempts)),
112
97
  lockWaitMs:
113
- event.lockWaitMs === undefined
114
- ? undefined
115
- : Math.max(0, Math.floor(event.lockWaitMs)),
98
+ event.lockWaitMs === undefined ? undefined : Math.max(0, Math.floor(event.lockWaitMs)),
116
99
  redisReadMs:
117
- event.redisReadMs === undefined
118
- ? undefined
119
- : Math.max(0, Math.floor(event.redisReadMs)),
100
+ event.redisReadMs === undefined ? undefined : Math.max(0, Math.floor(event.redisReadMs)),
120
101
  redisWriteMs:
121
- event.redisWriteMs === undefined
122
- ? undefined
123
- : Math.max(0, Math.floor(event.redisWriteMs)),
102
+ event.redisWriteMs === undefined ? undefined : Math.max(0, Math.floor(event.redisWriteMs)),
124
103
  poolAgeMs:
125
- event.poolAgeMs === undefined
126
- ? undefined
127
- : Math.max(0, Math.floor(event.poolAgeMs)),
104
+ event.poolAgeMs === undefined ? undefined : Math.max(0, Math.floor(event.poolAgeMs)),
128
105
  poolExpiresInMs:
129
106
  event.poolExpiresInMs === undefined
130
107
  ? undefined
131
108
  : Math.max(0, Math.floor(event.poolExpiresInMs)),
132
109
  attempts: Math.max(1, Math.floor(event.attempts || 1)),
133
110
  refreshes:
134
- event.refreshes === undefined
135
- ? undefined
136
- : Math.max(0, Math.floor(event.refreshes)),
111
+ event.refreshes === undefined ? undefined : Math.max(0, Math.floor(event.refreshes)),
137
112
  });
138
113
  }
139
114
 
@@ -148,9 +123,7 @@ export class ProxyTelemetryCollector implements ProxyTelemetrySink {
148
123
  ...(event.proxyHash ? { proxyHash: event.proxyHash.slice(0, 16) } : {}),
149
124
  outcome: event.outcome === "ok" ? "ok" : "error",
150
125
  ...(event.errorCode ? { errorCode: event.errorCode.slice(0, 80) } : {}),
151
- ...(event.status === undefined
152
- ? {}
153
- : { status: Math.max(0, Math.floor(event.status)) }),
126
+ ...(event.status === undefined ? {} : { status: Math.max(0, Math.floor(event.status)) }),
154
127
  ...(event.durationMs === undefined
155
128
  ? {}
156
129
  : { durationMs: Math.max(0, Math.floor(event.durationMs)) }),
@@ -170,18 +143,12 @@ export class ProxyTelemetryCollector implements ProxyTelemetrySink {
170
143
  allocatorMs: sumOptional(acc.allocatorMs, event.allocatorMs),
171
144
  allocatorStatus: event.allocatorStatus ?? acc.allocatorStatus,
172
145
  allocatorBodyClass: event.allocatorBodyClass ?? acc.allocatorBodyClass,
173
- allocatorAttempts: sumOptional(
174
- acc.allocatorAttempts,
175
- event.allocatorAttempts,
176
- ),
146
+ allocatorAttempts: sumOptional(acc.allocatorAttempts, event.allocatorAttempts),
177
147
  lockWaitMs: sumOptional(acc.lockWaitMs, event.lockWaitMs),
178
148
  redisReadMs: sumOptional(acc.redisReadMs, event.redisReadMs),
179
149
  redisWriteMs: sumOptional(acc.redisWriteMs, event.redisWriteMs),
180
150
  poolAgeMs: maxOptional(acc.poolAgeMs, event.poolAgeMs),
181
- poolExpiresInMs: maxOptional(
182
- acc.poolExpiresInMs,
183
- event.poolExpiresInMs,
184
- ),
151
+ poolExpiresInMs: maxOptional(acc.poolExpiresInMs, event.poolExpiresInMs),
185
152
  attempts: acc.attempts + event.attempts,
186
153
  refreshes: sumOptional(acc.refreshes, event.refreshes),
187
154
  }),
@@ -194,9 +161,7 @@ export class ProxyTelemetryCollector implements ProxyTelemetrySink {
194
161
  cacheStatus: aggregate.cacheStatus,
195
162
  cacheHit: aggregate.cacheHit,
196
163
  resolutionMs: aggregate.resolutionMs,
197
- ...(aggregate.allocatorMs !== undefined
198
- ? { allocatorMs: aggregate.allocatorMs }
199
- : {}),
164
+ ...(aggregate.allocatorMs !== undefined ? { allocatorMs: aggregate.allocatorMs } : {}),
200
165
  ...(aggregate.allocatorStatus !== undefined
201
166
  ? { allocatorStatus: aggregate.allocatorStatus }
202
167
  : {}),
@@ -206,40 +171,26 @@ export class ProxyTelemetryCollector implements ProxyTelemetrySink {
206
171
  ...(aggregate.allocatorAttempts !== undefined
207
172
  ? { allocatorAttempts: aggregate.allocatorAttempts }
208
173
  : {}),
209
- ...(aggregate.lockWaitMs !== undefined
210
- ? { lockWaitMs: aggregate.lockWaitMs }
211
- : {}),
212
- ...(aggregate.redisReadMs !== undefined
213
- ? { redisReadMs: aggregate.redisReadMs }
214
- : {}),
215
- ...(aggregate.redisWriteMs !== undefined
216
- ? { redisWriteMs: aggregate.redisWriteMs }
217
- : {}),
218
- ...(aggregate.poolAgeMs !== undefined
219
- ? { poolAgeMs: aggregate.poolAgeMs }
220
- : {}),
174
+ ...(aggregate.lockWaitMs !== undefined ? { lockWaitMs: aggregate.lockWaitMs } : {}),
175
+ ...(aggregate.redisReadMs !== undefined ? { redisReadMs: aggregate.redisReadMs } : {}),
176
+ ...(aggregate.redisWriteMs !== undefined ? { redisWriteMs: aggregate.redisWriteMs } : {}),
177
+ ...(aggregate.poolAgeMs !== undefined ? { poolAgeMs: aggregate.poolAgeMs } : {}),
221
178
  ...(aggregate.poolExpiresInMs !== undefined
222
179
  ? { poolExpiresInMs: aggregate.poolExpiresInMs }
223
180
  : {}),
224
181
  attempts: aggregate.attempts,
225
- ...(aggregate.refreshes !== undefined
226
- ? { refreshes: aggregate.refreshes }
227
- : {}),
182
+ ...(aggregate.refreshes !== undefined ? { refreshes: aggregate.refreshes } : {}),
228
183
  ...(this.#attempts.length > 0
229
184
  ? {
230
185
  attemptSamples: this.#attempts.map((attempt, index) => ({
231
186
  n: index + 1,
232
187
  a: attempt.attempt,
233
- ...(attempt.poolIndex === undefined
234
- ? {}
235
- : { i: attempt.poolIndex }),
188
+ ...(attempt.poolIndex === undefined ? {} : { i: attempt.poolIndex }),
236
189
  ...(attempt.proxyHash ? { h: attempt.proxyHash } : {}),
237
190
  o: attempt.outcome,
238
191
  ...(attempt.errorCode ? { c: attempt.errorCode } : {}),
239
192
  ...(attempt.status === undefined ? {} : { s: attempt.status }),
240
- ...(attempt.durationMs === undefined
241
- ? {}
242
- : { d: attempt.durationMs }),
193
+ ...(attempt.durationMs === undefined ? {} : { d: attempt.durationMs }),
243
194
  })),
244
195
  }
245
196
  : {}),
@@ -1,4 +1,4 @@
1
- import Redis from "ioredis";
1
+ import { Redis } from "ioredis";
2
2
 
3
3
  export type ProviderRedisClient = Redis;
4
4
 
@@ -43,9 +43,7 @@ export async function withRedisTimeout<T>(
43
43
  }
44
44
  }, options.timeoutMs);
45
45
  });
46
- const operationResult = options.onError
47
- ? operation().catch(options.onError)
48
- : operation();
46
+ const operationResult = options.onError ? operation().catch(options.onError) : operation();
49
47
  return await Promise.race([operationResult, timeout]);
50
48
  } finally {
51
49
  if (timeoutId) clearTimeout(timeoutId);
@@ -56,10 +54,7 @@ export function redisStatus(redis: ProviderRedisClient): string {
56
54
  return redis.status;
57
55
  }
58
56
 
59
- async function waitForRedisReady(
60
- redis: ProviderRedisClient,
61
- timeoutMs: number,
62
- ): Promise<boolean> {
57
+ async function waitForRedisReady(redis: ProviderRedisClient, timeoutMs: number): Promise<boolean> {
63
58
  let timeoutId: ReturnType<typeof setTimeout> | undefined;
64
59
  let settled = false;
65
60
 
@@ -80,10 +75,7 @@ async function waitForRedisReady(
80
75
  const onReady = () => finish(true);
81
76
  const onUnavailable = () => finish(false);
82
77
 
83
- timeoutId = setTimeout(
84
- () => finish(redisStatus(redis) === "ready"),
85
- timeoutMs,
86
- );
78
+ timeoutId = setTimeout(() => finish(redisStatus(redis) === "ready"), timeoutMs);
87
79
  redis.once("ready", onReady);
88
80
  redis.once("close", onUnavailable);
89
81
  redis.once("end", onUnavailable);
@@ -1,12 +1,6 @@
1
- import type {
2
- RequestParamPrimitive,
3
- RequestParams,
4
- RequestParamValue,
5
- } from "../types";
1
+ import type { RequestParamPrimitive, RequestParams, RequestParamValue } from "../types.js";
6
2
 
7
- function isParamArray(
8
- value: RequestParamValue,
9
- ): value is readonly RequestParamPrimitive[] {
3
+ function isParamArray(value: RequestParamValue): value is readonly RequestParamPrimitive[] {
10
4
  return Array.isArray(value);
11
5
  }
12
6
 
@@ -29,8 +23,7 @@ export function appendQueryParams(url: string, params?: RequestParams): string {
29
23
  const parsed = new URL(url);
30
24
  for (const [key, value] of Object.entries(params)) {
31
25
  if (isParamArray(value)) {
32
- for (const item of value)
33
- appendQueryValue(parsed.searchParams, key, item);
26
+ for (const item of value) appendQueryValue(parsed.searchParams, key, item);
34
27
  continue;
35
28
  }
36
29
  appendQueryValue(parsed.searchParams, key, value);
@@ -39,9 +32,7 @@ export function appendQueryParams(url: string, params?: RequestParams): string {
39
32
  return parsed.toString();
40
33
  }
41
34
 
42
- export function normalizeHttpRequestBody(
43
- body: unknown,
44
- ): string | Buffer | undefined {
35
+ export function normalizeHttpRequestBody(body: unknown): string | Buffer | undefined {
45
36
  if (body === undefined) {
46
37
  return undefined;
47
38
  }
@@ -1,5 +1,5 @@
1
- import { providerStateRedisUrlFromEnv } from "../config/loader";
2
- import { ProviderError } from "../errors";
1
+ import { providerStateRedisUrlFromEnv } from "../config/loader.js";
2
+ import { ProviderError } from "../errors.js";
3
3
  import type {
4
4
  ProviderRuntimeState,
5
5
  ProviderStateNamespace,
@@ -7,13 +7,13 @@ import type {
7
7
  StateNamespaceOptions,
8
8
  StateValue,
9
9
  StateWriteOptions,
10
- } from "../types";
10
+ } from "../types.js";
11
11
  import {
12
12
  createProviderRedisClient,
13
13
  ensureRedisReady,
14
14
  type ProviderRedisClient,
15
15
  withRedisTimeout,
16
- } from "./redis";
16
+ } from "./redis.js";
17
17
 
18
18
  const DEFAULT_REDIS_TIMEOUT_MS = 250;
19
19
  const REDIS_STATE_PREFIX = "apifuse:provider-state:v1";
@@ -57,37 +57,24 @@ async function withRequiredRedis<T>(operation: () => Promise<T>): Promise<T> {
57
57
  return await withRedisTimeout(operation, {
58
58
  timeoutMs: DEFAULT_REDIS_TIMEOUT_MS,
59
59
  onTimeout: () => {
60
- throw new UnsupportedProviderStateError(
61
- "Provider runtime state Redis timed out",
62
- );
60
+ throw new UnsupportedProviderStateError("Provider runtime state Redis timed out");
63
61
  },
64
62
  onError: () => {
65
- throw new UnsupportedProviderStateError(
66
- "Provider runtime state Redis is unavailable",
67
- );
63
+ throw new UnsupportedProviderStateError("Provider runtime state Redis is unavailable");
68
64
  },
69
65
  });
70
66
  }
71
67
 
72
68
  async function requireRedisReady(redis: ProviderRedisClient): Promise<void> {
73
69
  if (await ensureRedisReady(redis, DEFAULT_REDIS_TIMEOUT_MS)) return;
74
- throw new UnsupportedProviderStateError(
75
- "Provider runtime state Redis is unavailable",
76
- );
70
+ throw new UnsupportedProviderStateError("Provider runtime state Redis is unavailable");
77
71
  }
78
72
 
79
- function providerStatePrefix(
80
- providerId: string | undefined,
81
- namespace: string,
82
- ): string {
73
+ function providerStatePrefix(providerId: string | undefined, namespace: string): string {
83
74
  return `${REDIS_STATE_PREFIX}:${providerId ?? "default"}:${namespace}`;
84
75
  }
85
76
 
86
- function providerStateKey(
87
- providerId: string | undefined,
88
- namespace: string,
89
- key: string,
90
- ): string {
77
+ function providerStateKey(providerId: string | undefined, namespace: string, key: string): string {
91
78
  return `${providerStatePrefix(providerId, namespace)}:${key}`;
92
79
  }
93
80
 
@@ -132,9 +119,7 @@ function envelopeFromJson(
132
119
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
133
120
  return null;
134
121
  }
135
- const record: Record<string, unknown> = Object.fromEntries(
136
- Object.entries(parsed),
137
- );
122
+ const record: Record<string, unknown> = Object.fromEntries(Object.entries(parsed));
138
123
  if (
139
124
  typeof record.version !== "number" ||
140
125
  typeof record.expiresAt !== "string" ||
@@ -182,9 +167,7 @@ class RedisProviderStateNamespace implements ProviderStateNamespace {
182
167
 
183
168
  private async activeKeys(): Promise<string[]> {
184
169
  await requireRedisReady(this.backend.redis);
185
- return await withRequiredRedis(() =>
186
- this.backend.redis.keys(`${this.prefix()}*`),
187
- );
170
+ return await withRequiredRedis(() => this.backend.redis.keys(`${this.prefix()}*`));
188
171
  }
189
172
 
190
173
  private enforceValueSize(value: unknown): void {
@@ -207,47 +190,29 @@ class RedisProviderStateNamespace implements ProviderStateNamespace {
207
190
  }
208
191
  }
209
192
 
210
- async list<T>(options?: {
211
- limit?: number;
212
- prefix?: string;
213
- }): Promise<StateValue<T>[]> {
193
+ async list<T>(options?: { limit?: number; prefix?: string }): Promise<StateValue<T>[]> {
214
194
  const keys = (await this.activeKeys()).filter((key) => {
215
- const publicKey = publicStateKey(
216
- this.providerId,
217
- this.namespaceName,
218
- key,
219
- );
195
+ const publicKey = publicStateKey(this.providerId, this.namespaceName, key);
220
196
  return options?.prefix ? publicKey.startsWith(options.prefix) : true;
221
197
  });
222
198
  const limited = keys.slice(0, Math.max(0, options?.limit ?? keys.length));
223
199
  if (limited.length === 0) return [];
224
- const values = await withRequiredRedis(() =>
225
- this.backend.redis.mget(limited),
226
- );
200
+ const values = await withRequiredRedis(() => this.backend.redis.mget(limited));
227
201
  return values.flatMap((raw, index) => {
228
202
  const key = limited[index];
229
203
  if (!key) return [];
230
- const value = envelopeFromJson(
231
- publicStateKey(this.providerId, this.namespaceName, key),
232
- raw,
233
- );
204
+ const value = envelopeFromJson(publicStateKey(this.providerId, this.namespaceName, key), raw);
234
205
  return value ? [value] : [];
235
206
  });
236
207
  }
237
208
 
238
209
  async get<T>(key: string): Promise<StateValue<T> | null> {
239
210
  await requireRedisReady(this.backend.redis);
240
- const raw = await withRequiredRedis(() =>
241
- this.backend.redis.get(this.redisKey(key)),
242
- );
211
+ const raw = await withRequiredRedis(() => this.backend.redis.get(this.redisKey(key)));
243
212
  return envelopeFromJson(key, raw);
244
213
  }
245
214
 
246
- async set<T>(
247
- key: string,
248
- value: T,
249
- options?: StateWriteOptions,
250
- ): Promise<StateValue<T>> {
215
+ async set<T>(key: string, value: T, options?: StateWriteOptions): Promise<StateValue<T>> {
251
216
  this.enforceValueSize(value);
252
217
  await this.enforceMaxEntries(key);
253
218
  const current = await this.get<T>(key);
@@ -258,12 +223,7 @@ class RedisProviderStateNamespace implements ProviderStateNamespace {
258
223
  const expiresAt = resolveExpiresAt(ttl);
259
224
  const envelope = redisEnvelope(value, version, createdAt, expiresAt);
260
225
  await withRequiredRedis(() =>
261
- this.backend.redis.set(
262
- this.redisKey(key),
263
- JSON.stringify(envelope),
264
- "PX",
265
- ttlMs,
266
- ),
226
+ this.backend.redis.set(this.redisKey(key), JSON.stringify(envelope), "PX", ttlMs),
267
227
  );
268
228
  return {
269
229
  key,
@@ -313,11 +273,7 @@ class RedisProviderStateNamespace implements ProviderStateNamespace {
313
273
  ): Promise<StateValue<Record<string, unknown>>> {
314
274
  const current = (await this.get<Record<string, unknown>>(key))?.value ?? {};
315
275
  const previous = typeof current[field] === "number" ? current[field] : 0;
316
- return await this.set(
317
- key,
318
- { ...current, [field]: previous + delta },
319
- options,
320
- );
276
+ return await this.set(key, { ...current, [field]: previous + delta }, options);
321
277
  }
322
278
  }
323
279
 
@@ -330,43 +286,26 @@ class RedisProviderRuntimeState implements ProviderRuntimeState {
330
286
  this.providerId = options.providerId;
331
287
  }
332
288
 
333
- namespace(
334
- name: string,
335
- options: StateNamespaceOptions,
336
- ): ProviderStateNamespace {
337
- return new RedisProviderStateNamespace(
338
- this.backend,
339
- this.providerId,
340
- name,
341
- options,
342
- );
289
+ namespace(name: string, options: StateNamespaceOptions): ProviderStateNamespace {
290
+ return new RedisProviderStateNamespace(this.backend, this.providerId, name, options);
343
291
  }
344
292
  }
345
293
 
346
294
  export class UnsupportedProviderStateError extends ProviderError {
347
- constructor(
348
- message = "Provider runtime state is not available in this runtime",
349
- ) {
295
+ constructor(message = "Provider runtime state is not available in this runtime") {
350
296
  super(message, { code: "PROVIDER_STATE_UNSUPPORTED" });
351
297
  this.name = "UnsupportedProviderStateError";
352
298
  }
353
299
  }
354
300
 
355
301
  class UnsupportedProviderStateNamespace implements ProviderStateNamespace {
356
- async list<T>(_options?: {
357
- limit?: number;
358
- prefix?: string;
359
- }): Promise<StateValue<T>[]> {
302
+ async list<T>(_options?: { limit?: number; prefix?: string }): Promise<StateValue<T>[]> {
360
303
  throw new UnsupportedProviderStateError();
361
304
  }
362
305
  async get<T>(_key: string): Promise<StateValue<T> | null> {
363
306
  throw new UnsupportedProviderStateError();
364
307
  }
365
- async set<T>(
366
- _key: string,
367
- _value: T,
368
- _options?: StateWriteOptions,
369
- ): Promise<StateValue<T>> {
308
+ async set<T>(_key: string, _value: T, _options?: StateWriteOptions): Promise<StateValue<T>> {
370
309
  throw new UnsupportedProviderStateError();
371
310
  }
372
311
  async patch<T extends Record<string, unknown>>(
@@ -398,10 +337,7 @@ class UnsupportedProviderStateNamespace implements ProviderStateNamespace {
398
337
  }
399
338
 
400
339
  class UnsupportedProviderRuntimeState implements ProviderRuntimeState {
401
- namespace(
402
- _name: string,
403
- _options: StateNamespaceOptions,
404
- ): ProviderStateNamespace {
340
+ namespace(_name: string, _options: StateNamespaceOptions): ProviderStateNamespace {
405
341
  return new UnsupportedProviderStateNamespace();
406
342
  }
407
343
  }
@@ -420,10 +356,7 @@ class MemoryProviderStateNamespace implements ProviderStateNamespace {
420
356
  }
421
357
  }
422
358
 
423
- async list<T>(_options?: {
424
- limit?: number;
425
- prefix?: string;
426
- }): Promise<StateValue<T>[]> {
359
+ async list<T>(_options?: { limit?: number; prefix?: string }): Promise<StateValue<T>[]> {
427
360
  this.pruneExpired();
428
361
  const rows = Array.from(this.values.values()).filter((value) =>
429
362
  _options?.prefix ? value.key.startsWith(_options.prefix) : true,
@@ -436,17 +369,11 @@ class MemoryProviderStateNamespace implements ProviderStateNamespace {
436
369
  return this.values.get(key) ?? null;
437
370
  }
438
371
 
439
- async set<T>(
440
- key: string,
441
- value: T,
442
- options?: StateWriteOptions,
443
- ): Promise<StateValue<T>> {
372
+ async set<T>(key: string, value: T, options?: StateWriteOptions): Promise<StateValue<T>> {
444
373
  this.pruneExpired();
445
374
  const now = new Date().toISOString();
446
375
  const current = this.values.get(key);
447
- const expiresAt = resolveMemoryStateExpiresAt(
448
- options?.ttl ?? this.options.defaultTtl,
449
- );
376
+ const expiresAt = resolveMemoryStateExpiresAt(options?.ttl ?? this.options.defaultTtl);
450
377
  const row = {
451
378
  key,
452
379
  value,
@@ -499,10 +426,7 @@ class MemoryProviderStateNamespace implements ProviderStateNamespace {
499
426
  class MemoryProviderRuntimeState implements ProviderRuntimeState {
500
427
  readonly namespaces = new Map<string, MemoryProviderStateNamespace>();
501
428
 
502
- namespace(
503
- name: string,
504
- _options: StateNamespaceOptions,
505
- ): ProviderStateNamespace {
429
+ namespace(name: string, _options: StateNamespaceOptions): ProviderStateNamespace {
506
430
  const existing = this.namespaces.get(name);
507
431
  if (existing) return existing;
508
432
  const created = new MemoryProviderStateNamespace(_options);
@@ -536,10 +460,7 @@ export function createRedisProviderRuntimeState(
536
460
  }
537
461
 
538
462
  export function createProviderRuntimeStateFromEnv(
539
- options: {
540
- readonly providerId?: string;
541
- readonly allowMemoryFallback?: boolean;
542
- } = {},
463
+ options: { readonly providerId?: string; readonly allowMemoryFallback?: boolean } = {},
543
464
  ): ProviderRuntimeState {
544
465
  const redisUrl = providerStateRedisUrlFromEnv();
545
466
  if (redisUrl) {
@@ -2,16 +2,16 @@ import { createHash } from "node:crypto";
2
2
  import type { Browser, ImpitOptions, ImpitResponse, RequestInit } from "impit";
3
3
  import { Impit } from "impit";
4
4
 
5
- import type { ProxyResolutionOptions } from "../config/loader";
5
+ import type { ProxyResolutionOptions } from "../config/loader.js";
6
6
  import {
7
7
  DEFAULT_SMARTPROXY_POOL_SIZE,
8
8
  invalidateProxyResolutionCacheAsync,
9
9
  ProxyResolutionError,
10
10
  resolveProxyConfigAsync,
11
11
  SMARTPROXY_MAX_POOL_SIZE,
12
- } from "../config/loader";
13
- import { SDKError, TransportError } from "../errors";
14
- import { getStealthProfile } from "../stealth/profiles";
12
+ } from "../config/loader.js";
13
+ import { SDKError, TransportError } from "../errors.js";
14
+ import { getStealthProfile } from "../stealth/profiles.js";
15
15
  import type {
16
16
  CookieJar,
17
17
  HttpMethod,
@@ -20,7 +20,7 @@ import type {
20
20
  StealthRedirectHop,
21
21
  StealthResponse,
22
22
  StealthSession,
23
- } from "../types";
23
+ } from "../types.js";
24
24
  import {
25
25
  createProxyAuthIpDeniedError,
26
26
  createProxyEdgeAuthRejectedError,
@@ -35,7 +35,7 @@ import {
35
35
  isProxyPoolStaleStatus,
36
36
  PROXY_EDGE_AUTH_REJECTED_CODE,
37
37
  PROXY_POOL_STALE_CODE,
38
- } from "./proxy-errors";
38
+ } from "./proxy-errors.js";
39
39
  import {
40
40
  computeProxyAttemptIndex,
41
41
  computeProxyTransportRetryDelayMs,
@@ -43,8 +43,8 @@ import {
43
43
  normalizeProxyTransportRetryOptions,
44
44
  shouldRetryProxyTransportAttempt,
45
45
  validateUnsafeProxyTransportRetryMethods,
46
- } from "./proxy-retry-policy";
47
- import { appendQueryParams } from "./request-options";
46
+ } from "./proxy-retry-policy.js";
47
+ import { appendQueryParams } from "./request-options.js";
48
48
 
49
49
  const DEFAULT_PROFILE = "chrome-146";
50
50