@apifuse/provider-sdk 2.2.0-beta.11 → 2.2.0-beta.13
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/AUTHORING.md +238 -0
- package/CHANGELOG.md +14 -0
- package/README.md +44 -2
- package/bin/apifuse-pack-smoke.ts +14 -0
- package/bin/apifuse-pack-types.ts +40 -1
- package/bin/apifuse-record.ts +622 -57
- package/bin/apifuse-submit-check.ts +43 -10
- package/dist/config/loader.d.ts +9 -1
- package/dist/config/loader.js +9 -0
- package/dist/define.d.ts +2 -1
- package/dist/define.js +61 -3
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +15 -0
- package/dist/fixture-sanitization.d.ts +26 -0
- package/dist/fixture-sanitization.js +216 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/provider.d.ts +2 -1
- package/dist/provider.js +1 -0
- package/dist/runtime/http.js +86 -32
- package/dist/runtime/instrumentation.js +295 -9
- package/dist/runtime/native-network.d.ts +53 -0
- package/dist/runtime/native-network.js +477 -0
- package/dist/runtime/proxy-nodemaven.d.ts +14 -0
- package/dist/runtime/proxy-nodemaven.js +20 -2
- package/dist/runtime/request-options.d.ts +68 -1
- package/dist/runtime/request-options.js +548 -0
- package/dist/runtime/stealth.d.ts +3 -1
- package/dist/runtime/stealth.js +352 -86
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/self-test-input-tokens.d.ts +2 -1
- package/dist/server/self-test-input-tokens.js +18 -14
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +451 -19
- package/dist/types.d.ts +201 -7
- package/package.json +3 -1
- package/src/config/loader.ts +22 -1
- package/src/define.ts +81 -3
- package/src/errors.ts +15 -0
- package/src/fixture-sanitization.ts +247 -0
- package/src/index.ts +45 -1
- package/src/provider.ts +37 -0
- package/src/runtime/http.ts +144 -38
- package/src/runtime/instrumentation.ts +424 -8
- package/src/runtime/native-network.ts +600 -0
- package/src/runtime/proxy-nodemaven.ts +37 -2
- package/src/runtime/request-options.ts +680 -1
- package/src/runtime/stealth.ts +420 -88
- package/src/server/index.ts +4 -1
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/stream-evidence.ts +988 -0
- package/src/testing/index.ts +9 -1
- package/src/testing/run.ts +608 -12
- package/src/types.ts +235 -7
package/src/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type ms from "ms";
|
|
2
|
+
import type { SerializedCookieJar } from "tough-cookie";
|
|
2
3
|
|
|
3
4
|
import type { infer as ZodInfer, ZodType } from "zod";
|
|
4
5
|
|
|
@@ -823,6 +824,12 @@ export interface ProviderProxyPolicy {
|
|
|
823
824
|
affinity?: ProviderProxySessionAffinity;
|
|
824
825
|
lifetimeMinutes?: number;
|
|
825
826
|
poolSize?: number;
|
|
827
|
+
/**
|
|
828
|
+
* Seconds before hard sticky expiry at which native connections receive
|
|
829
|
+
* the `expiring` event so the provider can drain and reconnect cleanly.
|
|
830
|
+
* Declared by the provider; the SDK does not assume a default cut point.
|
|
831
|
+
*/
|
|
832
|
+
drainLeadSeconds?: number;
|
|
826
833
|
};
|
|
827
834
|
}
|
|
828
835
|
|
|
@@ -999,6 +1006,11 @@ export interface HttpRetrySummary {
|
|
|
999
1006
|
export interface RequestOptions {
|
|
1000
1007
|
headers?: Record<string, string>;
|
|
1001
1008
|
params?: RequestParams;
|
|
1009
|
+
/**
|
|
1010
|
+
* Query parameters whose values contain credentials or other secret material.
|
|
1011
|
+
* They are sent like `params`, but redacted from SDK errors, traces, and recorded fixtures.
|
|
1012
|
+
*/
|
|
1013
|
+
sensitiveParams?: Record<string, string>;
|
|
1002
1014
|
proxy?: string;
|
|
1003
1015
|
timeout?: number;
|
|
1004
1016
|
/**
|
|
@@ -1031,6 +1043,12 @@ export interface StealthFetchOptions extends RequestOptions {
|
|
|
1031
1043
|
method?: HttpMethod;
|
|
1032
1044
|
body?: string | Buffer;
|
|
1033
1045
|
redirect?: "follow" | "manual" | "error";
|
|
1046
|
+
/**
|
|
1047
|
+
* Maximum decoded response-body bytes to buffer. When set, the stealth
|
|
1048
|
+
* transport aborts the response and throws `response_too_large` if the
|
|
1049
|
+
* declared or streamed body exceeds this limit.
|
|
1050
|
+
*/
|
|
1051
|
+
maxBodyBytes?: number;
|
|
1034
1052
|
/**
|
|
1035
1053
|
* Offsets policy-managed proxy pool selection for caller-managed retries.
|
|
1036
1054
|
* Use when a request receives an upstream challenge page rather than a
|
|
@@ -1051,18 +1069,45 @@ export interface StealthFetchOptions extends RequestOptions {
|
|
|
1051
1069
|
}
|
|
1052
1070
|
|
|
1053
1071
|
export interface CookieJar {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1072
|
+
/** URL-less reads use the jar's response URL or session base URL. */
|
|
1073
|
+
get(name: string, url?: string): string | undefined;
|
|
1074
|
+
getAll(url?: string): Record<string, string>;
|
|
1075
|
+
toString(url?: string): string;
|
|
1076
|
+
find?(predicate: (cookie: string) => boolean, url?: string): string | undefined;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* Version 1 of the JSON-safe, attribute-preserving stealth cookie store.
|
|
1081
|
+
* The nested jar is tough-cookie's serialized form and retains cookie origin,
|
|
1082
|
+
* Path, Secure, expiry, host-only, and other RFC attributes.
|
|
1083
|
+
*/
|
|
1084
|
+
export interface StealthCookieStoreV1 {
|
|
1085
|
+
readonly version: 1;
|
|
1086
|
+
readonly jar: SerializedCookieJar;
|
|
1058
1087
|
}
|
|
1059
1088
|
|
|
1089
|
+
/** Cookie persistence formats understood by this SDK version. */
|
|
1090
|
+
export type StealthCookieStore = StealthCookieStoreV1;
|
|
1091
|
+
|
|
1060
1092
|
export interface StealthSessionCookies extends CookieJar {
|
|
1061
|
-
has(name: string): boolean;
|
|
1062
|
-
|
|
1063
|
-
|
|
1093
|
+
has(name: string, url?: string): boolean;
|
|
1094
|
+
/** URL-less writes are scoped to the session base URL. */
|
|
1095
|
+
setFromCookieStrings(cookieStrings: readonly string[], url?: string): void;
|
|
1096
|
+
toHeader(url?: string): string;
|
|
1097
|
+
/**
|
|
1098
|
+
* Returns every cookie as a flat name/value map, collapsing duplicate names.
|
|
1099
|
+
* @deprecated Use serialize() for lossless, attribute-preserving persistence.
|
|
1100
|
+
*/
|
|
1064
1101
|
snapshot(): Record<string, string>;
|
|
1102
|
+
/**
|
|
1103
|
+
* Restores flat values as host-only, Path=/ cookies on the session base URL.
|
|
1104
|
+
* @deprecated Use deserialize() with state produced by serialize().
|
|
1105
|
+
*/
|
|
1065
1106
|
restore(cookies: Record<string, string>): void;
|
|
1107
|
+
/** Returns a versioned, JSON-safe, attribute-preserving representation of every cookie. */
|
|
1108
|
+
serialize(): StealthCookieStoreV1;
|
|
1109
|
+
/** Replaces the jar with a previously serialized, attribute-preserving cookie store. */
|
|
1110
|
+
deserialize(state: StealthCookieStore): void;
|
|
1066
1111
|
clear(): void;
|
|
1067
1112
|
}
|
|
1068
1113
|
|
|
@@ -1108,7 +1153,13 @@ export interface StealthRedirectRunResult {
|
|
|
1108
1153
|
final: StealthResponse;
|
|
1109
1154
|
hops: StealthRedirectHop[];
|
|
1110
1155
|
reason: "completed" | "stopped" | "max_hops" | "missing_location" | "loop";
|
|
1156
|
+
/**
|
|
1157
|
+
* Complete flat view across all redirect hosts. Attributes and duplicate names are lost.
|
|
1158
|
+
* @deprecated Use cookieStore for lossless persistence.
|
|
1159
|
+
*/
|
|
1111
1160
|
cookies: Record<string, string>;
|
|
1161
|
+
/** Versioned, attribute-preserving cookie state accumulated across the redirect chain. */
|
|
1162
|
+
cookieStore: StealthCookieStoreV1;
|
|
1112
1163
|
}
|
|
1113
1164
|
|
|
1114
1165
|
export interface StealthSession {
|
|
@@ -1198,6 +1249,171 @@ export interface HttpClient {
|
|
|
1198
1249
|
): Promise<AsyncIterable<SseMessage>>;
|
|
1199
1250
|
}
|
|
1200
1251
|
|
|
1252
|
+
/** Request-scoped file reference accepted by provider operation inputs. */
|
|
1253
|
+
export interface ProviderFileRef {
|
|
1254
|
+
readonly type: "request_file";
|
|
1255
|
+
readonly id: string;
|
|
1256
|
+
readonly filename: string;
|
|
1257
|
+
readonly mime_type?: string;
|
|
1258
|
+
readonly size: number;
|
|
1259
|
+
readonly sha256?: string;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/** File body resolved from a request-scoped {@link ProviderFileRef}. */
|
|
1263
|
+
export type ProviderResolvedFile = Omit<ProviderFileRef, "mime_type"> & {
|
|
1264
|
+
readonly mimeType?: string;
|
|
1265
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
1266
|
+
bytes(): Promise<Uint8Array>;
|
|
1267
|
+
stream(): ReadableStream<Uint8Array>;
|
|
1268
|
+
};
|
|
1269
|
+
|
|
1270
|
+
/** Resolver supplied by runtimes that accept request-scoped file inputs. */
|
|
1271
|
+
export interface ProviderFilesContext {
|
|
1272
|
+
has(input: string | ProviderFileRef): boolean;
|
|
1273
|
+
resolve(input: string | ProviderFileRef): Promise<ProviderResolvedFile>;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
export type NativeTcpTlsMode = "required" | "allowed" | "disabled";
|
|
1277
|
+
|
|
1278
|
+
export interface NativeTcpPortRange {
|
|
1279
|
+
readonly start: number;
|
|
1280
|
+
readonly end: number;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
/** Static native TCP egress declared by a provider. */
|
|
1284
|
+
export interface NativeTcpEgressRule {
|
|
1285
|
+
readonly host: string;
|
|
1286
|
+
readonly ports: readonly number[];
|
|
1287
|
+
readonly tls: NativeTcpTlsMode;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
/**
|
|
1291
|
+
* Bounded native TCP egress discovered through a declared bootstrap endpoint.
|
|
1292
|
+
* Host suffixes are exact DNS suffixes, not wildcard patterns.
|
|
1293
|
+
*/
|
|
1294
|
+
export interface NativeTcpDynamicEgressRule {
|
|
1295
|
+
readonly sourceHost?: string;
|
|
1296
|
+
readonly sourceHostSuffixes?: readonly string[];
|
|
1297
|
+
readonly sourcePorts?: readonly number[];
|
|
1298
|
+
readonly sourcePortRanges?: readonly NativeTcpPortRange[];
|
|
1299
|
+
readonly targetHostSuffixes: readonly string[];
|
|
1300
|
+
readonly targetPorts?: readonly number[];
|
|
1301
|
+
readonly targetPortRanges?: readonly NativeTcpPortRange[];
|
|
1302
|
+
readonly tls: NativeTcpTlsMode;
|
|
1303
|
+
readonly ttlMs?: number;
|
|
1304
|
+
readonly maxGrants?: number;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
/** Common TCP/TLS connection input supported by the native runtime. */
|
|
1308
|
+
export interface NativeNetworkConnectInput {
|
|
1309
|
+
readonly host: string;
|
|
1310
|
+
readonly port: number;
|
|
1311
|
+
readonly serverName?: string;
|
|
1312
|
+
readonly rejectUnauthorized?: boolean;
|
|
1313
|
+
/**
|
|
1314
|
+
* Maximum time without a successful socket read before the connection is
|
|
1315
|
+
* closed. Opt-in; when absent, reads can remain pending indefinitely.
|
|
1316
|
+
*/
|
|
1317
|
+
readonly idleTimeoutMs?: number;
|
|
1318
|
+
/** Maximum time allowed to establish the TCP/SOCKS/TLS connection. */
|
|
1319
|
+
readonly timeoutMs?: number;
|
|
1320
|
+
readonly signal?: AbortSignal;
|
|
1321
|
+
/** Overrides the credential-derived sticky affinity key. */
|
|
1322
|
+
readonly affinityKey?: string;
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
export type NativeNetworkConnectOptions = Omit<
|
|
1326
|
+
NativeNetworkConnectInput,
|
|
1327
|
+
"serverName" | "rejectUnauthorized"
|
|
1328
|
+
>;
|
|
1329
|
+
|
|
1330
|
+
export type NativeTlsConnectOptions = NativeNetworkConnectInput;
|
|
1331
|
+
|
|
1332
|
+
export interface NativeNetworkDynamicGrantOptions {
|
|
1333
|
+
readonly sourceHost: string;
|
|
1334
|
+
readonly sourcePort: number;
|
|
1335
|
+
readonly host: string;
|
|
1336
|
+
readonly port: number;
|
|
1337
|
+
readonly tls: NativeTcpTlsMode;
|
|
1338
|
+
readonly ttlMs?: number;
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
export interface NativeNetworkEgressGrant {
|
|
1342
|
+
revoke(): void;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
/** Consumer-facing alias used by native TCP providers. */
|
|
1346
|
+
export type NativeTcpEgressGrant = NativeNetworkEgressGrant;
|
|
1347
|
+
|
|
1348
|
+
/** Resolved egress identity for a native connection routed through a proxy. */
|
|
1349
|
+
export interface NativeProxyEgressInfo {
|
|
1350
|
+
readonly vendor: ProviderProxyProvider;
|
|
1351
|
+
readonly sticky: boolean;
|
|
1352
|
+
/** Vendor sticky session id (sid). Absent for rotating sessions. */
|
|
1353
|
+
readonly sessionId?: string;
|
|
1354
|
+
/** Hard expiry of the sticky binding, ISO 8601. */
|
|
1355
|
+
readonly expiresAt?: string;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
export type NativeProxyExpiringReason = "sticky_expiry";
|
|
1359
|
+
|
|
1360
|
+
export interface NativeProxyExpiringEvent {
|
|
1361
|
+
readonly expiresAt: string;
|
|
1362
|
+
readonly leadSeconds: number;
|
|
1363
|
+
readonly reason: NativeProxyExpiringReason;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
/**
|
|
1367
|
+
* Cooperative drain handler. The SDK awaits this before closing a socket whose
|
|
1368
|
+
* sticky proxy binding is about to expire, then force-closes at hard expiry.
|
|
1369
|
+
*/
|
|
1370
|
+
export type NativeProxyDrainHandler = (
|
|
1371
|
+
event: NativeProxyExpiringEvent,
|
|
1372
|
+
) => void | Promise<void>;
|
|
1373
|
+
|
|
1374
|
+
/** Typed reason recorded when the SDK closes a native connection intentionally. */
|
|
1375
|
+
export interface NativeNetworkCloseReason {
|
|
1376
|
+
readonly code: string;
|
|
1377
|
+
readonly message: string;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
/** Byte-oriented connection returned by the native TCP/TLS runtime. */
|
|
1381
|
+
export interface NativeNetworkConnection {
|
|
1382
|
+
/** Present when the connection was routed through a proxy. */
|
|
1383
|
+
readonly proxy?: NativeProxyEgressInfo;
|
|
1384
|
+
/** Present after an SDK-planned close, such as sticky proxy expiry. */
|
|
1385
|
+
readonly closeReason?: NativeNetworkCloseReason;
|
|
1386
|
+
/** Register a cooperative drain handler for sticky-expiry reconnects. */
|
|
1387
|
+
onExpiring?(handler: NativeProxyDrainHandler): void;
|
|
1388
|
+
read(): Promise<Uint8Array | null>;
|
|
1389
|
+
write(data: Uint8Array): Promise<void>;
|
|
1390
|
+
close(): Promise<void>;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
export interface NativeNetworkClient {
|
|
1394
|
+
connectTcp(
|
|
1395
|
+
input: NativeNetworkConnectOptions,
|
|
1396
|
+
): Promise<NativeNetworkConnection>;
|
|
1397
|
+
connectTls(input: NativeTlsConnectOptions): Promise<NativeNetworkConnection>;
|
|
1398
|
+
grantTcpEgress(
|
|
1399
|
+
input: NativeNetworkDynamicGrantOptions,
|
|
1400
|
+
): NativeNetworkEgressGrant;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
export interface NativeContext {
|
|
1404
|
+
readonly network: NativeNetworkClient;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
/** Consumer-facing alias for the native capability on provider contexts. */
|
|
1408
|
+
export type NativeProviderContext = NativeContext;
|
|
1409
|
+
|
|
1410
|
+
export interface NativeProviderConfig {
|
|
1411
|
+
readonly network?: {
|
|
1412
|
+
readonly tcp?: readonly NativeTcpEgressRule[];
|
|
1413
|
+
readonly dynamicTcp?: readonly NativeTcpDynamicEgressRule[];
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1201
1417
|
export interface ProviderCacheKeyOptions {
|
|
1202
1418
|
/**
|
|
1203
1419
|
* Additional field names to omit from stable key material. The SDK always
|
|
@@ -1615,6 +1831,8 @@ export interface FlowContext {
|
|
|
1615
1831
|
tenantId: string;
|
|
1616
1832
|
providerId: string;
|
|
1617
1833
|
http: HttpClient;
|
|
1834
|
+
/** Present when the selected runtime supplies native network capabilities. */
|
|
1835
|
+
readonly native?: NativeProviderContext;
|
|
1618
1836
|
stealth: StealthClient;
|
|
1619
1837
|
env: EnvContext;
|
|
1620
1838
|
credential?: CredentialContext;
|
|
@@ -1734,6 +1952,10 @@ export interface ProviderContext {
|
|
|
1734
1952
|
credential: CredentialContext;
|
|
1735
1953
|
request?: ProviderRequestContext;
|
|
1736
1954
|
http: HttpClient;
|
|
1955
|
+
/** Present for requests carrying runtime-resolvable file references. */
|
|
1956
|
+
readonly files?: ProviderFilesContext;
|
|
1957
|
+
/** Present when the selected runtime supplies native network capabilities. */
|
|
1958
|
+
readonly native?: NativeProviderContext;
|
|
1737
1959
|
cache: ProviderCache;
|
|
1738
1960
|
state: ProviderRuntimeState;
|
|
1739
1961
|
stealth: StealthClient;
|
|
@@ -1826,6 +2048,11 @@ export interface OperationDefinition<
|
|
|
1826
2048
|
fixtures?: {
|
|
1827
2049
|
request: InferSchemaOutput<TInput>;
|
|
1828
2050
|
response: InferSchemaOutput<TOutput>;
|
|
2051
|
+
/**
|
|
2052
|
+
* KST calendar date when `response` evidence was captured. Date fields in
|
|
2053
|
+
* the response align with this date, not a resolved relative request date.
|
|
2054
|
+
*/
|
|
2055
|
+
recordedAt?: string;
|
|
1829
2056
|
};
|
|
1830
2057
|
upstream?: {
|
|
1831
2058
|
baseUrl?: string;
|
|
@@ -1889,6 +2116,7 @@ export interface ProviderDefinition {
|
|
|
1889
2116
|
*/
|
|
1890
2117
|
deployment?: ProviderDeploymentOverrides;
|
|
1891
2118
|
allowedHosts?: string[];
|
|
2119
|
+
native?: NativeProviderConfig;
|
|
1892
2120
|
stealth?: {
|
|
1893
2121
|
profile: string;
|
|
1894
2122
|
platform: StealthPlatform;
|