@apifuse/provider-sdk 2.2.0-beta.22 → 2.2.0-beta.24
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.
- package/CHANGELOG.md +8 -0
- package/bin/apifuse-dev.ts +4 -0
- package/bin/apifuse-pack-types.ts +234 -38
- package/bin/apifuse-perf.ts +15 -12
- package/bin/apifuse-record.ts +4 -0
- package/dist/config/loader.d.ts +8 -19
- package/dist/config/loader.js +28 -86
- package/dist/contract-types.d.ts +1 -0
- package/dist/contract.js +2 -0
- package/dist/define.d.ts +5 -1
- package/dist/define.js +79 -6
- package/dist/error-resolution.js +5 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -0
- package/dist/provider.d.ts +1 -1
- package/dist/runtime/auth-flow.d.ts +2 -1
- package/dist/runtime/auth-flow.js +4 -0
- package/dist/runtime/browser.js +78 -9
- package/dist/runtime/http.js +0 -1
- package/dist/runtime/instrumentation.js +26 -1
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +440 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +8 -0
- package/dist/runtime/resolver-vendors/bindings.js +15 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +24 -0
- package/dist/runtime/resolver-vendors/browser.js +287 -0
- package/dist/runtime/resolver-vendors/types.d.ts +42 -0
- package/dist/runtime/resolver-vendors/types.js +57 -0
- package/dist/runtime/resolver.d.ts +39 -0
- package/dist/runtime/resolver.js +414 -0
- package/dist/runtime/state.d.ts +3 -0
- package/dist/runtime/state.js +245 -141
- package/dist/runtime/stealth.js +3 -6
- package/dist/runtime/stt.js +1 -12
- package/dist/runtime/timeout.d.ts +5 -0
- package/dist/runtime/timeout.js +12 -0
- package/dist/server/serve.d.ts +6 -1
- package/dist/server/serve.js +39 -8
- package/dist/testing/run.js +10 -0
- package/dist/types.d.ts +163 -4
- package/package.json +1 -1
- package/src/config/loader.ts +35 -111
- package/src/contract-types.ts +1 -0
- package/src/contract.ts +2 -0
- package/src/define.ts +121 -7
- package/src/error-resolution.ts +5 -0
- package/src/index.ts +45 -1
- package/src/provider.ts +1 -0
- package/src/runtime/auth-flow.ts +6 -0
- package/src/runtime/browser.ts +139 -19
- package/src/runtime/http.ts +0 -1
- package/src/runtime/instrumentation.ts +36 -2
- package/src/runtime/ocr.ts +523 -0
- package/src/runtime/resolver-vendors/bindings.ts +31 -0
- package/src/runtime/resolver-vendors/browser.ts +420 -0
- package/src/runtime/resolver-vendors/types.ts +113 -0
- package/src/runtime/resolver.ts +668 -0
- package/src/runtime/state.ts +323 -166
- package/src/runtime/stealth.ts +3 -6
- package/src/runtime/stt.ts +1 -19
- package/src/runtime/timeout.ts +18 -0
- package/src/server/serve.ts +80 -5
- package/src/testing/run.ts +15 -0
- package/src/types.ts +188 -4
package/dist/server/serve.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { type ProviderErrorCategory } from "../observability.js";
|
|
4
|
-
import type { ProviderContext, ProviderDefinition, ProviderRuntimeState, SttContext } from "../types.js";
|
|
4
|
+
import type { OcrContext, ProviderContext, ProviderDefinition, ProviderRuntimeState, ResolverContext, SttContext } from "../types.js";
|
|
5
5
|
import { type OperationRequest } from "./types.js";
|
|
6
6
|
/** Compact SDK-owned error classification emitted separately from the public response body. */
|
|
7
7
|
export declare const ERROR_OBSERVABILITY_HEADER = "X-ApiFuse-Error-Observability";
|
|
@@ -61,6 +61,7 @@ export type ProviderServerOperationExecutorInput = {
|
|
|
61
61
|
};
|
|
62
62
|
export type ProviderServerOperationExecutor = (input: ProviderServerOperationExecutorInput) => Promise<unknown>;
|
|
63
63
|
export declare function resolveProviderProxyAffinityKey(provider: ProviderDefinition, request: OperationRequest, operationId: string): string;
|
|
64
|
+
export declare function resolveProviderResolverIdentityScope(provider: ProviderDefinition, affinityKey: string, contextId: string): string;
|
|
64
65
|
type ProviderRequestCost = {
|
|
65
66
|
durationMs: number;
|
|
66
67
|
cpuUserMicros: number;
|
|
@@ -133,6 +134,10 @@ export type ProviderServerOptions = {
|
|
|
133
134
|
};
|
|
134
135
|
/** Optional STT override for tests or custom hosts; local/prod normally resolves from env. */
|
|
135
136
|
stt?: SttContext;
|
|
137
|
+
/** Optional OCR override for tests or custom hosts; local/prod normally resolves from env. */
|
|
138
|
+
ocr?: OcrContext;
|
|
139
|
+
/** Optional resolver override for tests or custom hosts; local/prod normally resolves from env. */
|
|
140
|
+
resolver?: ResolverContext;
|
|
136
141
|
/** Optional runtime state override for tests or custom hosts. Production resolves Redis from env and fails closed when unavailable. */
|
|
137
142
|
state?: ProviderRuntimeState;
|
|
138
143
|
/** Allow process-local runtime state only for local development and tests. */
|
package/dist/server/serve.js
CHANGED
|
@@ -18,8 +18,10 @@ import { createHttpClient } from "../runtime/http.js";
|
|
|
18
18
|
import { wrapWithInstrumentation } from "../runtime/instrumentation.js";
|
|
19
19
|
import { createEnvVendorCredentialResolver, createNativeNetworkClient, } from "../runtime/native-network.js";
|
|
20
20
|
import { getProviderBaseUrl } from "../runtime/provider.js";
|
|
21
|
+
import { createOcrClientFromEnv } from "../runtime/ocr.js";
|
|
21
22
|
import { PROXY_AUTH_IP_DENIED_CODE, PROXY_EDGE_AUTH_REJECTED_CODE, PROXY_POOL_EXHAUSTED_CODE, } from "../runtime/proxy-errors.js";
|
|
22
23
|
import { PROVIDER_TELEMETRY_HEADER, ProxyTelemetryCollector } from "../runtime/proxy-telemetry.js";
|
|
24
|
+
import { bindResolverSignal, createResolverClientFromEnv } from "../runtime/resolver.js";
|
|
23
25
|
import { assertRequiredSecretsPresent, listMissingRequiredSecrets, MISSING_SECRET_CODE, } from "../runtime/secrets.js";
|
|
24
26
|
import { createProviderRuntimeStateFromEnv, createUnsupportedProviderRuntimeState, } from "../runtime/state.js";
|
|
25
27
|
import { createStealthClient } from "../runtime/stealth.js";
|
|
@@ -148,6 +150,13 @@ export function resolveProviderProxyAffinityKey(provider, request, operationId)
|
|
|
148
150
|
}
|
|
149
151
|
return connectionKey ?? provider.id;
|
|
150
152
|
}
|
|
153
|
+
export function resolveProviderResolverIdentityScope(provider, affinityKey, contextId) {
|
|
154
|
+
return JSON.stringify({
|
|
155
|
+
proxy: provider.proxy ?? null,
|
|
156
|
+
affinityKey,
|
|
157
|
+
contextId,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
151
160
|
function resolveOperationConnectionId(request) {
|
|
152
161
|
return request.connection?.id ?? request.connectionId;
|
|
153
162
|
}
|
|
@@ -160,7 +169,7 @@ function resolveNativeProxyPolicy(provider) {
|
|
|
160
169
|
return { mode: "disabled" };
|
|
161
170
|
return undefined;
|
|
162
171
|
}
|
|
163
|
-
function createProviderContext(provider, request, operationId, options = {}, state = createUnsupportedProviderRuntimeState(), proxyTelemetry) {
|
|
172
|
+
function createProviderContext(provider, request, operationId, options = {}, state = createUnsupportedProviderRuntimeState(), proxyTelemetry, signal) {
|
|
164
173
|
const baseUrl = getProviderBaseUrl(provider);
|
|
165
174
|
const stealthBaseUrl = getProviderStealthBaseUrl(provider);
|
|
166
175
|
const stealthProfile = getProviderStealthProfile(provider);
|
|
@@ -169,6 +178,7 @@ function createProviderContext(provider, request, operationId, options = {}, sta
|
|
|
169
178
|
affinityKey: resolveProviderProxyAffinityKey(provider, request, operationId),
|
|
170
179
|
telemetry: proxyTelemetry,
|
|
171
180
|
};
|
|
181
|
+
const resolverIdentityScope = resolveProviderResolverIdentityScope(provider, proxyClientOptions.affinityKey, request.requestId);
|
|
172
182
|
let wrappedContext;
|
|
173
183
|
const stealthClientOptions = {
|
|
174
184
|
upstream: proxyClientOptions.upstream,
|
|
@@ -189,6 +199,8 @@ function createProviderContext(provider, request, operationId, options = {}, sta
|
|
|
189
199
|
connectionId: resolveOperationConnectionId(request),
|
|
190
200
|
headers: request.headers ?? {},
|
|
191
201
|
};
|
|
202
|
+
const requestState = state.forConnection(requestContext.connectionId);
|
|
203
|
+
const cache = createProviderCache({ providerId: provider.id });
|
|
192
204
|
const context = wrapWithInstrumentation({
|
|
193
205
|
env,
|
|
194
206
|
credential,
|
|
@@ -201,8 +213,8 @@ function createProviderContext(provider, request, operationId, options = {}, sta
|
|
|
201
213
|
retryResponseMeta.set(wrappedContext, summary);
|
|
202
214
|
},
|
|
203
215
|
}),
|
|
204
|
-
cache
|
|
205
|
-
state,
|
|
216
|
+
cache,
|
|
217
|
+
state: requestState,
|
|
206
218
|
stealth: stealthBaseUrl
|
|
207
219
|
? stealthProfile
|
|
208
220
|
? createStealthClient(stealthBaseUrl, stealthProfile.name, stealthClientOptions)
|
|
@@ -232,13 +244,20 @@ function createProviderContext(provider, request, operationId, options = {}, sta
|
|
|
232
244
|
: {}),
|
|
233
245
|
trace: createTraceContext(),
|
|
234
246
|
auth: createAuthStub(),
|
|
247
|
+
ocr: options.ocr ?? createOcrClientFromEnv(provider.ocr),
|
|
235
248
|
stt: options.stt ?? createSttClientFromEnv(provider.stt),
|
|
249
|
+
resolver: bindResolverSignal(options.resolver ??
|
|
250
|
+
createResolverClientFromEnv(provider.resolver, undefined, {
|
|
251
|
+
allowedHosts: provider.allowedHosts,
|
|
252
|
+
cache,
|
|
253
|
+
identityScope: resolverIdentityScope,
|
|
254
|
+
}), signal),
|
|
236
255
|
choice: createProviderChoiceContext({
|
|
237
256
|
providerId: provider.id,
|
|
238
257
|
env,
|
|
239
258
|
request: requestContext,
|
|
240
259
|
credential,
|
|
241
|
-
state,
|
|
260
|
+
state: requestState,
|
|
242
261
|
}),
|
|
243
262
|
});
|
|
244
263
|
wrappedContext = context;
|
|
@@ -282,6 +301,7 @@ function createAuthFlowContext(provider, request, options = {}, signal) {
|
|
|
282
301
|
request.providerId ??
|
|
283
302
|
provider.id,
|
|
284
303
|
};
|
|
304
|
+
const resolverIdentityScope = resolveProviderResolverIdentityScope(provider, proxyClientOptions.affinityKey, request.requestId);
|
|
285
305
|
const stealthClientOptions = {
|
|
286
306
|
upstream: proxyClientOptions.upstream,
|
|
287
307
|
affinityKey: proxyClientOptions.affinityKey,
|
|
@@ -294,6 +314,7 @@ function createAuthFlowContext(provider, request, options = {}, signal) {
|
|
|
294
314
|
values: request.connection.secrets,
|
|
295
315
|
})
|
|
296
316
|
: undefined;
|
|
317
|
+
const cache = createProviderCache({ providerId: provider.id });
|
|
297
318
|
return {
|
|
298
319
|
context: {
|
|
299
320
|
flowId: request.flowId,
|
|
@@ -327,7 +348,14 @@ function createAuthFlowContext(provider, request, options = {}, signal) {
|
|
|
327
348
|
]),
|
|
328
349
|
credential,
|
|
329
350
|
context: flowContextStore.context,
|
|
351
|
+
ocr: options.ocr ?? createOcrClientFromEnv(provider.ocr),
|
|
330
352
|
stt: options.stt ?? createSttClientFromEnv(provider.stt),
|
|
353
|
+
resolver: bindResolverSignal(options.resolver ??
|
|
354
|
+
createResolverClientFromEnv(provider.resolver, undefined, {
|
|
355
|
+
allowedHosts: provider.allowedHosts,
|
|
356
|
+
cache,
|
|
357
|
+
identityScope: resolverIdentityScope,
|
|
358
|
+
}), signal),
|
|
331
359
|
auth: createAuthFlowHelpers({ signal }),
|
|
332
360
|
},
|
|
333
361
|
getPatch: flowContextStore.getPatch,
|
|
@@ -1045,8 +1073,8 @@ function withAuthRequestHeaders(request, headers) {
|
|
|
1045
1073
|
},
|
|
1046
1074
|
};
|
|
1047
1075
|
}
|
|
1048
|
-
async function handleOperation(provider, request, operationId, options = {}, state = createUnsupportedProviderRuntimeState(), proxyTelemetry) {
|
|
1049
|
-
const ctx = createProviderContext(provider, request, operationId, options, state, proxyTelemetry);
|
|
1076
|
+
async function handleOperation(provider, request, operationId, options = {}, state = createUnsupportedProviderRuntimeState(), proxyTelemetry, signal) {
|
|
1077
|
+
const ctx = createProviderContext(provider, request, operationId, options, state, proxyTelemetry, signal);
|
|
1050
1078
|
const operation = provider.operations[operationId];
|
|
1051
1079
|
const streaming = operation?.transport?.kind && operation.transport.kind !== "json";
|
|
1052
1080
|
let cleanupCalled = false;
|
|
@@ -1074,6 +1102,7 @@ async function handleOperation(provider, request, operationId, options = {}, sta
|
|
|
1074
1102
|
operationId,
|
|
1075
1103
|
ctx,
|
|
1076
1104
|
request,
|
|
1105
|
+
signal,
|
|
1077
1106
|
})
|
|
1078
1107
|
: await executeOperation(provider, operationId, ctx, request.input);
|
|
1079
1108
|
if (streaming && operation) {
|
|
@@ -1393,7 +1422,7 @@ export function createServerApp(provider, options = {}) {
|
|
|
1393
1422
|
}
|
|
1394
1423
|
const request = operationRequestFromForwardingEnvelope(envelope);
|
|
1395
1424
|
operationId = envelope.operationId;
|
|
1396
|
-
const ctx = createProviderContext(provider, request, operationId, options, state);
|
|
1425
|
+
const ctx = createProviderContext(provider, request, operationId, options, state, undefined, signal);
|
|
1397
1426
|
if (deadlineAtMs !== undefined && deadlineAtMs <= Date.now()) {
|
|
1398
1427
|
throw new StatefulRoutingDeadlineError(envelope.requestId, envelope.deadlineAt);
|
|
1399
1428
|
}
|
|
@@ -1432,7 +1461,7 @@ export function createServerApp(provider, options = {}) {
|
|
|
1432
1461
|
const body = OperationRequestSchema.parse(rawBody);
|
|
1433
1462
|
const requestHeaders = Object.fromEntries(c.req.raw.headers.entries());
|
|
1434
1463
|
body.headers = { ...requestHeaders, ...body.headers };
|
|
1435
|
-
const response = await handleOperation(provider, body, operation, options, state, proxyTelemetry);
|
|
1464
|
+
const response = await handleOperation(provider, body, operation, options, state, proxyTelemetry, c.req.raw.signal);
|
|
1436
1465
|
if (response instanceof Response) {
|
|
1437
1466
|
logProviderSuccess(logger, provider, "operation", operation, body.requestId, response.status, finishRequestCost(requestCost));
|
|
1438
1467
|
return responseWithProviderTelemetry(response, proxyTelemetry);
|
|
@@ -1608,7 +1637,9 @@ export async function serve(provider, options = {}) {
|
|
|
1608
1637
|
const configuredSignals = resolveShutdownSignals(options.shutdown?.signals ?? true);
|
|
1609
1638
|
const app = createServerApp(provider, {
|
|
1610
1639
|
logger: options.logger,
|
|
1640
|
+
ocr: options.ocr,
|
|
1611
1641
|
stt: options.stt,
|
|
1642
|
+
resolver: options.resolver,
|
|
1612
1643
|
state: options.state,
|
|
1613
1644
|
allowMemoryStateFallback: options.allowMemoryStateFallback,
|
|
1614
1645
|
operationExecutor: options.operationExecutor,
|
package/dist/testing/run.js
CHANGED
|
@@ -2,6 +2,7 @@ import { describe, expect, it } from "bun:test";
|
|
|
2
2
|
import { createProviderCache } from "../runtime/cache.js";
|
|
3
3
|
import { createTestProviderChoiceContext } from "../runtime/choice.js";
|
|
4
4
|
import { createMemoryProviderRuntimeState } from "../runtime/state.js";
|
|
5
|
+
import { createUnsupportedOcrClient } from "../runtime/ocr.js";
|
|
5
6
|
import { createUnsupportedSttClient } from "../runtime/stt.js";
|
|
6
7
|
import { createNativeEgressAuthorization, NativeNetworkError, snapshotNativeConnectInput, snapshotNativeGrantInput, } from "../runtime/native-network.js";
|
|
7
8
|
import { safeParseSchemaSync } from "../schema.js";
|
|
@@ -247,6 +248,7 @@ function createUpstreamContext(provider, operationName, upstreamStub) {
|
|
|
247
248
|
},
|
|
248
249
|
}),
|
|
249
250
|
close: async () => { },
|
|
251
|
+
cookies: async () => (await browserAction("cookies")).data,
|
|
250
252
|
fill: async (selector, textValue) => {
|
|
251
253
|
await browserAction("fill", { selector, text: textValue });
|
|
252
254
|
},
|
|
@@ -397,7 +399,11 @@ function createUpstreamContext(provider, operationName, upstreamStub) {
|
|
|
397
399
|
: {}),
|
|
398
400
|
trace: { span: async (_name, fn) => fn() },
|
|
399
401
|
auth: { requestField: async (name) => unsupported(`ctx.auth.requestField(${name})`) },
|
|
402
|
+
ocr: createUnsupportedOcrClient("Standard test upstream context does not support ctx.ocr.recognize"),
|
|
400
403
|
stt: createUnsupportedSttClient("Standard test upstream context does not support ctx.stt.transcribe"),
|
|
404
|
+
resolver: {
|
|
405
|
+
solve: async () => unsupported("ctx.resolver.solve"),
|
|
406
|
+
},
|
|
401
407
|
choice: createTestProviderChoiceContext({
|
|
402
408
|
providerId: `standard-test-${operationName}`,
|
|
403
409
|
request,
|
|
@@ -503,7 +509,11 @@ export function createSnapshotContext(rawFixture) {
|
|
|
503
509
|
auth: {
|
|
504
510
|
requestField: async (name) => unsupported(`ctx.auth.requestField(${name})`),
|
|
505
511
|
},
|
|
512
|
+
ocr: createUnsupportedOcrClient("Standard test snapshot context does not support ctx.ocr.recognize"),
|
|
506
513
|
stt: createUnsupportedSttClient("Standard test snapshot context does not support ctx.stt.transcribe"),
|
|
514
|
+
resolver: {
|
|
515
|
+
solve: async () => unsupported("ctx.resolver.solve"),
|
|
516
|
+
},
|
|
507
517
|
choice: createTestProviderChoiceContext({
|
|
508
518
|
providerId: "standard-test",
|
|
509
519
|
request,
|
package/dist/types.d.ts
CHANGED
|
@@ -196,6 +196,54 @@ export interface SmsOtpMatcherDefinition {
|
|
|
196
196
|
/** Runtime/fixture helper. Not serialized into generated registry artifacts. */
|
|
197
197
|
extractOtp(body: string): string | null;
|
|
198
198
|
}
|
|
199
|
+
export interface ProviderOcrConfig {
|
|
200
|
+
readonly mode: "required" | "optional";
|
|
201
|
+
}
|
|
202
|
+
export type OcrImageInput = {
|
|
203
|
+
readonly kind: "base64";
|
|
204
|
+
readonly data: string;
|
|
205
|
+
readonly mediaType?: string;
|
|
206
|
+
} | {
|
|
207
|
+
readonly kind: "url";
|
|
208
|
+
readonly url: string;
|
|
209
|
+
};
|
|
210
|
+
export interface OcrRecognizeRequest {
|
|
211
|
+
readonly image: OcrImageInput;
|
|
212
|
+
readonly hint?: "captcha" | "document" | "generic";
|
|
213
|
+
readonly prompt?: string;
|
|
214
|
+
readonly maxTokens?: number;
|
|
215
|
+
readonly timeoutMs?: number;
|
|
216
|
+
}
|
|
217
|
+
export interface OcrWarning {
|
|
218
|
+
readonly code: string;
|
|
219
|
+
readonly message: string;
|
|
220
|
+
}
|
|
221
|
+
export interface OcrResult {
|
|
222
|
+
readonly text: string;
|
|
223
|
+
readonly model: string;
|
|
224
|
+
readonly warnings?: readonly OcrWarning[];
|
|
225
|
+
}
|
|
226
|
+
export interface OcrCaptchaOptions {
|
|
227
|
+
readonly length?: number;
|
|
228
|
+
/** Allowed characters. A RegExp is applied to each character, not to the whole text. */
|
|
229
|
+
readonly charset?: string | RegExp;
|
|
230
|
+
readonly caseSensitive?: boolean;
|
|
231
|
+
readonly maxCandidates?: number;
|
|
232
|
+
}
|
|
233
|
+
export interface OcrCaptchaCandidate {
|
|
234
|
+
readonly text: string;
|
|
235
|
+
readonly satisfiesConstraints: boolean;
|
|
236
|
+
}
|
|
237
|
+
export interface OcrCaptchaResult {
|
|
238
|
+
readonly text: string;
|
|
239
|
+
readonly candidates: readonly OcrCaptchaCandidate[];
|
|
240
|
+
readonly satisfiesConstraints: boolean;
|
|
241
|
+
readonly model: string;
|
|
242
|
+
}
|
|
243
|
+
export interface OcrContext {
|
|
244
|
+
recognize(request: OcrRecognizeRequest): Promise<OcrResult>;
|
|
245
|
+
extractCaptchaText(image: OcrImageInput, options?: OcrCaptchaOptions): Promise<OcrCaptchaResult>;
|
|
246
|
+
}
|
|
199
247
|
export type SttTranscribeMode = "general" | "otp";
|
|
200
248
|
export type SttPromptPolicy = "none" | "default-hint" | "custom-hint";
|
|
201
249
|
export type SttUnsupportedOptionPolicy = "warn" | "error";
|
|
@@ -203,6 +251,79 @@ export type ProviderSttMode = "optional" | "required";
|
|
|
203
251
|
export interface ProviderSttConfig {
|
|
204
252
|
mode: ProviderSttMode;
|
|
205
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* `browser` is the in-house CDP pool (`apps/cdp-pool`, reached through
|
|
256
|
+
* `createBrowserClient`) and is a first-class vendor rather than an escape hatch:
|
|
257
|
+
* for fingerprint-family kinds, it was measured faster than a paid vendor
|
|
258
|
+
* (4.5 s vs 17.5 s) at zero marginal cost.
|
|
259
|
+
*
|
|
260
|
+
* `2captcha` is the vendor already carrying production traffic in
|
|
261
|
+
* `apifuse-provider-tabelog`.
|
|
262
|
+
*
|
|
263
|
+
* Union order is documentation only; the effective fallback order is whatever
|
|
264
|
+
* `ProviderResolverConfig.vendors` declares.
|
|
265
|
+
*/
|
|
266
|
+
export type ProviderResolverVendor = "browser" | "capsolver" | "capmonster" | "2captcha" | "custom";
|
|
267
|
+
/**
|
|
268
|
+
* Token-family kinds resolve to `{ form: "token" }`. Cookie-family kinds resolve
|
|
269
|
+
* to `{ form: "cookies" }`; network-identity binding is defined per kind. `aws_waf`
|
|
270
|
+
* was measured portable across residential leases on buyee, while `cf_clearance`
|
|
271
|
+
* remains unmeasured here and is treated as identity-scoped because it is widely
|
|
272
|
+
* described as IP-bound.
|
|
273
|
+
*/
|
|
274
|
+
export type ProviderChallenge = {
|
|
275
|
+
readonly kind: "turnstile";
|
|
276
|
+
readonly siteKey: string;
|
|
277
|
+
readonly pageUrl: string;
|
|
278
|
+
readonly action?: string;
|
|
279
|
+
readonly cdata?: string;
|
|
280
|
+
} | {
|
|
281
|
+
readonly kind: "recaptcha_v2";
|
|
282
|
+
readonly siteKey: string;
|
|
283
|
+
readonly pageUrl: string;
|
|
284
|
+
} | {
|
|
285
|
+
readonly kind: "recaptcha_v3";
|
|
286
|
+
readonly siteKey: string;
|
|
287
|
+
readonly pageUrl: string;
|
|
288
|
+
readonly action: string;
|
|
289
|
+
readonly minScore?: number;
|
|
290
|
+
} | {
|
|
291
|
+
readonly kind: "hcaptcha";
|
|
292
|
+
readonly siteKey: string;
|
|
293
|
+
readonly pageUrl: string;
|
|
294
|
+
} | {
|
|
295
|
+
readonly kind: "cloudflare_interstitial";
|
|
296
|
+
readonly pageUrl: string;
|
|
297
|
+
readonly blockedHtml?: string;
|
|
298
|
+
} | {
|
|
299
|
+
readonly kind: "aws_waf";
|
|
300
|
+
readonly pageUrl: string;
|
|
301
|
+
readonly captchaScript?: string;
|
|
302
|
+
readonly context?: string;
|
|
303
|
+
readonly iv?: string;
|
|
304
|
+
};
|
|
305
|
+
export type ProviderChallengeKind = ProviderChallenge["kind"];
|
|
306
|
+
/**
|
|
307
|
+
* Token solutions carry no network-identity binding. Cookie-solution binding is
|
|
308
|
+
* per challenge kind: `aws_waf` was measured portable across residential leases
|
|
309
|
+
* on buyee, while `cf_clearance` is unmeasured here and treated as scoped to the
|
|
310
|
+
* identity that produced it. The provider attaches the returned cookies to its
|
|
311
|
+
* own requests.
|
|
312
|
+
*/
|
|
313
|
+
export type ChallengeSolution = {
|
|
314
|
+
readonly form: "token";
|
|
315
|
+
readonly token: string;
|
|
316
|
+
} | {
|
|
317
|
+
readonly form: "cookies";
|
|
318
|
+
readonly cookies: Readonly<Record<string, string>>;
|
|
319
|
+
readonly userAgent: string;
|
|
320
|
+
};
|
|
321
|
+
export interface ProviderResolverConfig {
|
|
322
|
+
/** Ordered vendor fallback chain, tried first to last. */
|
|
323
|
+
readonly vendors: readonly ProviderResolverVendor[];
|
|
324
|
+
/** Challenge kinds this provider is permitted to request. */
|
|
325
|
+
readonly kinds: readonly ProviderChallengeKind[];
|
|
326
|
+
}
|
|
206
327
|
export type SttAudioInput = {
|
|
207
328
|
kind: "base64";
|
|
208
329
|
data: string;
|
|
@@ -267,6 +388,9 @@ export interface SttContext {
|
|
|
267
388
|
transcribe(request: SttTranscribeRequest): Promise<SttTranscript>;
|
|
268
389
|
extractVerificationCode(text: string, options?: SttVerificationCodeOptions): VerificationCodeExtractionResult;
|
|
269
390
|
}
|
|
391
|
+
export interface ResolverContext {
|
|
392
|
+
solve(challenge: ProviderChallenge, signal?: AbortSignal): Promise<ChallengeSolution>;
|
|
393
|
+
}
|
|
270
394
|
export interface HealthJourneySchedule {
|
|
271
395
|
kind: "interval";
|
|
272
396
|
/** ISO 8601 duration, for example PT8H. */
|
|
@@ -668,10 +792,12 @@ export type ProviderProxyMode = "disabled" | "optional" | "required";
|
|
|
668
792
|
* - `decodo` — **decodo.com**, the *gateway* proxy that was named "Smartproxy"
|
|
669
793
|
* (smartproxy.com) before its 2025 rebrand to Decodo. Sticky sessions via
|
|
670
794
|
* username params. A different company from `smartproxy` above.
|
|
671
|
-
* **@deprecated** — unused; no managed adapter.
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
795
|
+
* **@deprecated** — unused; no managed adapter. Declare a
|
|
796
|
+
* `ProviderProxyPolicy` using `smartproxy` or `nodemaven` instead; the
|
|
797
|
+
* `smartproxy` allocator requires `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
|
|
798
|
+
* - `custom` — **@deprecated** static proxy marker with no managed adapter.
|
|
799
|
+
* Use `ProviderProxyPolicy` with `smartproxy`/`nodemaven`; the `smartproxy`
|
|
800
|
+
* allocator requires `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
|
|
675
801
|
*/
|
|
676
802
|
export type ProviderProxyProvider = "smartproxy" | "nodemaven" | "decodo" | "custom";
|
|
677
803
|
export type ProviderProxySessionAffinity = "request" | "operation" | "auth-flow" | "connection";
|
|
@@ -1281,6 +1407,17 @@ export interface BrowserFrame {
|
|
|
1281
1407
|
evaluate<T>(fn: string | (() => T)): Promise<T>;
|
|
1282
1408
|
locator(selector: string): BrowserLocator;
|
|
1283
1409
|
}
|
|
1410
|
+
export interface BrowserCookie {
|
|
1411
|
+
readonly name: string;
|
|
1412
|
+
readonly value: string;
|
|
1413
|
+
readonly domain: string;
|
|
1414
|
+
readonly path: string;
|
|
1415
|
+
/** Unix seconds. Absent for a session cookie. */
|
|
1416
|
+
readonly expires?: number;
|
|
1417
|
+
readonly httpOnly: boolean;
|
|
1418
|
+
readonly secure: boolean;
|
|
1419
|
+
readonly sameSite?: "Strict" | "Lax" | "None";
|
|
1420
|
+
}
|
|
1284
1421
|
export type BrowserResourceMethod = "GET" | "HEAD";
|
|
1285
1422
|
export type BrowserResourceRequest = {
|
|
1286
1423
|
readonly url: string;
|
|
@@ -1309,6 +1446,11 @@ export type BrowserResourcePolicy = {
|
|
|
1309
1446
|
};
|
|
1310
1447
|
export interface BrowserPage extends BrowserFrame {
|
|
1311
1448
|
close(): Promise<void>;
|
|
1449
|
+
/**
|
|
1450
|
+
* Reads the browser context's cookie jar, including httpOnly cookies.
|
|
1451
|
+
* Cookie expiry values are Unix seconds and are absent for session cookies.
|
|
1452
|
+
*/
|
|
1453
|
+
cookies(): Promise<readonly BrowserCookie[]>;
|
|
1312
1454
|
fill(selector: string, text: string): Promise<void>;
|
|
1313
1455
|
goto(url: string): Promise<void>;
|
|
1314
1456
|
pageId?: string;
|
|
@@ -1543,7 +1685,9 @@ export interface FlowContext {
|
|
|
1543
1685
|
env: EnvContext;
|
|
1544
1686
|
credential?: CredentialContext;
|
|
1545
1687
|
context: ContextScratchpad;
|
|
1688
|
+
ocr: OcrContext;
|
|
1546
1689
|
stt: SttContext;
|
|
1690
|
+
resolver: ResolverContext;
|
|
1547
1691
|
auth: AuthFlowTerminalContext;
|
|
1548
1692
|
}
|
|
1549
1693
|
export interface AuthTurn {
|
|
@@ -1575,7 +1719,13 @@ export interface AuthFlowDefinition {
|
|
|
1575
1719
|
refresh?: AuthFlowInputHandler;
|
|
1576
1720
|
}
|
|
1577
1721
|
export type ProviderStateDurationString = `${number}${"ms" | "s" | "m" | "h" | "d"}` | `PT${string}`;
|
|
1722
|
+
export type StateNamespaceScope = "connection" | "provider";
|
|
1578
1723
|
export interface StateNamespaceOptions {
|
|
1724
|
+
/**
|
|
1725
|
+
* State isolation boundary. Connection scope is the default; provider scope
|
|
1726
|
+
* must be selected explicitly for provider-wide coordination state.
|
|
1727
|
+
*/
|
|
1728
|
+
scope?: StateNamespaceScope;
|
|
1579
1729
|
/** Default TTL used when a write omits ttl. Required to avoid unbounded state. */
|
|
1580
1730
|
defaultTtl: ProviderStateDurationString;
|
|
1581
1731
|
/** Maximum allowed TTL; writes are rejected when they exceed this policy. */
|
|
@@ -1617,6 +1767,11 @@ export interface ProviderStateNamespace {
|
|
|
1617
1767
|
increment(key: string, field: string, delta?: number, options?: StateWriteOptions): Promise<StateValue<Record<string, unknown>>>;
|
|
1618
1768
|
}
|
|
1619
1769
|
export interface ProviderRuntimeState {
|
|
1770
|
+
/**
|
|
1771
|
+
* Returns an immutable view bound to one request connection. An unresolved
|
|
1772
|
+
* connection uses an isolated reserved sentinel, never the provider-global scope.
|
|
1773
|
+
*/
|
|
1774
|
+
forConnection(connectionId: string | undefined): ProviderRuntimeState;
|
|
1620
1775
|
namespace(name: string, options: StateNamespaceOptions): ProviderStateNamespace;
|
|
1621
1776
|
}
|
|
1622
1777
|
export interface ProviderContext {
|
|
@@ -1634,7 +1789,9 @@ export interface ProviderContext {
|
|
|
1634
1789
|
browser: BrowserClient;
|
|
1635
1790
|
trace: TraceContext;
|
|
1636
1791
|
auth: AuthContext;
|
|
1792
|
+
ocr: OcrContext;
|
|
1637
1793
|
stt: SttContext;
|
|
1794
|
+
resolver: ResolverContext;
|
|
1638
1795
|
choice: ProviderChoiceContext;
|
|
1639
1796
|
}
|
|
1640
1797
|
export interface ProxiedOAuthConfig {
|
|
@@ -1785,7 +1942,9 @@ export interface ProviderDefinition {
|
|
|
1785
1942
|
platform: StealthPlatform;
|
|
1786
1943
|
};
|
|
1787
1944
|
proxy?: ProviderProxyConfig;
|
|
1945
|
+
ocr?: ProviderOcrConfig;
|
|
1788
1946
|
stt?: ProviderSttConfig;
|
|
1947
|
+
resolver?: ProviderResolverConfig;
|
|
1789
1948
|
browser?: {
|
|
1790
1949
|
engine: BrowserEngine;
|
|
1791
1950
|
};
|
package/package.json
CHANGED