@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.
Files changed (59) hide show
  1. package/AUTHORING.md +238 -0
  2. package/CHANGELOG.md +14 -0
  3. package/README.md +44 -2
  4. package/bin/apifuse-pack-smoke.ts +14 -0
  5. package/bin/apifuse-pack-types.ts +40 -1
  6. package/bin/apifuse-record.ts +622 -57
  7. package/bin/apifuse-submit-check.ts +43 -10
  8. package/dist/config/loader.d.ts +9 -1
  9. package/dist/config/loader.js +9 -0
  10. package/dist/define.d.ts +2 -1
  11. package/dist/define.js +61 -3
  12. package/dist/errors.d.ts +5 -0
  13. package/dist/errors.js +15 -0
  14. package/dist/fixture-sanitization.d.ts +26 -0
  15. package/dist/fixture-sanitization.js +216 -0
  16. package/dist/index.d.ts +4 -3
  17. package/dist/index.js +2 -1
  18. package/dist/provider.d.ts +2 -1
  19. package/dist/provider.js +1 -0
  20. package/dist/runtime/http.js +86 -32
  21. package/dist/runtime/instrumentation.js +295 -9
  22. package/dist/runtime/native-network.d.ts +53 -0
  23. package/dist/runtime/native-network.js +477 -0
  24. package/dist/runtime/proxy-nodemaven.d.ts +14 -0
  25. package/dist/runtime/proxy-nodemaven.js +20 -2
  26. package/dist/runtime/request-options.d.ts +68 -1
  27. package/dist/runtime/request-options.js +548 -0
  28. package/dist/runtime/stealth.d.ts +3 -1
  29. package/dist/runtime/stealth.js +352 -86
  30. package/dist/server/index.d.ts +1 -1
  31. package/dist/server/index.js +1 -1
  32. package/dist/server/self-test-input-tokens.d.ts +2 -1
  33. package/dist/server/self-test-input-tokens.js +18 -14
  34. package/dist/stream-evidence.d.ts +74 -0
  35. package/dist/stream-evidence.js +785 -0
  36. package/dist/testing/index.d.ts +1 -1
  37. package/dist/testing/index.js +1 -1
  38. package/dist/testing/run.d.ts +32 -2
  39. package/dist/testing/run.js +451 -19
  40. package/dist/types.d.ts +201 -7
  41. package/package.json +3 -1
  42. package/src/config/loader.ts +22 -1
  43. package/src/define.ts +81 -3
  44. package/src/errors.ts +15 -0
  45. package/src/fixture-sanitization.ts +247 -0
  46. package/src/index.ts +45 -1
  47. package/src/provider.ts +37 -0
  48. package/src/runtime/http.ts +144 -38
  49. package/src/runtime/instrumentation.ts +424 -8
  50. package/src/runtime/native-network.ts +600 -0
  51. package/src/runtime/proxy-nodemaven.ts +37 -2
  52. package/src/runtime/request-options.ts +680 -1
  53. package/src/runtime/stealth.ts +420 -88
  54. package/src/server/index.ts +4 -1
  55. package/src/server/self-test-input-tokens.ts +29 -14
  56. package/src/stream-evidence.ts +988 -0
  57. package/src/testing/index.ts +9 -1
  58. package/src/testing/run.ts +608 -12
  59. package/src/types.ts +235 -7
@@ -11,10 +11,7 @@ import * as acorn from "acorn";
11
11
  import { z } from "zod";
12
12
 
13
13
  import packageJson from "../package.json";
14
- import {
15
- formatPromptAssetIssues,
16
- verifyPromptAssets,
17
- } from "../src/cli/prompt-assets.js";
14
+ import { formatPromptAssetIssues, verifyPromptAssets } from "../src/cli/prompt-assets.js";
18
15
  import {
19
16
  loadProviderLocaleCatalogs,
20
17
  type ProviderLocale,
@@ -22,6 +19,11 @@ import {
22
19
  } from "../src/i18n/index.js";
23
20
  import type { ProviderDefinition } from "../src/index.js";
24
21
  import { APIFUSE_DESCRIPTION_KEY_META_KEY, safeParseSchemaSync } from "../src/schema.js";
22
+ import {
23
+ findStreamCaptureGroup,
24
+ hasStreamEvidenceMarker,
25
+ parseStreamEvidenceRecord,
26
+ } from "../src/stream-evidence.js";
25
27
  import { type CheckResult, PROMPT_ASSETS_CHECK_MESSAGE, runChecks } from "./apifuse-check.js";
26
28
  import { hasSubstantiveDelimitedTextStructure } from "./submit-check-delimited-text.js";
27
29
  import { hasSubstantiveXmlStructure } from "./submit-check-xml.js";
@@ -2174,11 +2176,16 @@ const GENERATED_LOCAL_ONLY_SCAFFOLD_REASON = /generated local-only scaffold/i;
2174
2176
  function scoreFixtureProvenance(providerRoot: string, provider: ProviderDefinition): SubmitCheck {
2175
2177
  const rawPath = resolve(providerRoot, "__fixtures__", "raw.json");
2176
2178
  let hasRecordedEvidence = false;
2179
+ let fixtureValidationError: string | undefined;
2177
2180
  if (existsSync(rawPath)) {
2178
2181
  try {
2179
- hasRecordedEvidence = hasNonEmptyRecordedFixture(JSON.parse(readFileSync(rawPath, "utf8")));
2180
- } catch {
2182
+ hasRecordedEvidence = recordedFixtureStats(
2183
+ JSON.parse(readFileSync(rawPath, "utf8")),
2184
+ 0,
2185
+ ).hasNestedSubstance;
2186
+ } catch (error) {
2181
2187
  hasRecordedEvidence = false;
2188
+ fixtureValidationError = error instanceof Error ? error.message : String(error);
2182
2189
  }
2183
2190
  }
2184
2191
 
@@ -2190,6 +2197,16 @@ function scoreFixtureProvenance(providerRoot: string, provider: ProviderDefiniti
2190
2197
  0,
2191
2198
  );
2192
2199
  }
2200
+ if (fixtureValidationError) {
2201
+ return blocker(
2202
+ "fixture-provenance",
2203
+ "fixtures",
2204
+ `Malformed recorded fixture evidence in __fixtures__/raw.json: ${fixtureValidationError}`,
2205
+ "Re-run `bun run record` to replace the malformed stream evidence, or repair the named field using the stream evidence contract.",
2206
+ 0,
2207
+ ["__fixtures__/raw.json"],
2208
+ );
2209
+ }
2193
2210
 
2194
2211
  if (allOperationsAreGeneratedLocalScaffold(provider)) {
2195
2212
  return {
@@ -2218,13 +2235,31 @@ function scoreFixtureProvenance(providerRoot: string, provider: ProviderDefiniti
2218
2235
  }
2219
2236
 
2220
2237
  export function hasNonEmptyRecordedFixture(value: unknown): boolean {
2221
- return recordedFixtureStats(value, 0).hasNestedSubstance;
2238
+ try {
2239
+ return recordedFixtureStats(value, 0).hasNestedSubstance;
2240
+ } catch {
2241
+ return false;
2242
+ }
2222
2243
  }
2223
2244
 
2224
2245
  function recordedFixtureStats(
2225
2246
  value: unknown,
2226
2247
  depth: number,
2227
2248
  ): { hasNestedSubstance: boolean; leafValues: number } {
2249
+ if (
2250
+ value !== null &&
2251
+ typeof value === "object" &&
2252
+ !Array.isArray(value) &&
2253
+ (value as Record<string, unknown>).__apifuse_capture__ === true
2254
+ ) {
2255
+ const group = findStreamCaptureGroup(value);
2256
+ if (!group) throw new Error("Stream capture envelope is invalid.");
2257
+ return { hasNestedSubstance: true, leafValues: group.items.length };
2258
+ }
2259
+ if (hasStreamEvidenceMarker(value)) {
2260
+ parseStreamEvidenceRecord(value);
2261
+ return { hasNestedSubstance: true, leafValues: 1 };
2262
+ }
2228
2263
  if (value === null || value === undefined) {
2229
2264
  return { hasNestedSubstance: false, leafValues: 0 };
2230
2265
  }
@@ -4027,9 +4062,7 @@ type LineStringLiteral = {
4027
4062
  // Stable identity for the container a literal sits in ("top" when the
4028
4063
  // literal is not inside any bracket on the line).
4029
4064
  function literalContainerKey(literal: LineStringLiteral): string {
4030
- return literal.container
4031
- ? `${literal.container.bracket}${literal.container.index}`
4032
- : "top";
4065
+ return literal.container ? `${literal.container.bracket}${literal.container.index}` : "top";
4033
4066
  }
4034
4067
 
4035
4068
  // Single-pass line tokenizer: extracts every string literal with its span and
@@ -112,10 +112,13 @@ export type ProxyTelemetrySink = {
112
112
  recordProxyAttempt?(event: ProxyAttemptTelemetryEvent): void;
113
113
  recordProxyVendorFailover?(event: ProxyVendorFailoverTelemetryEvent): void;
114
114
  };
115
+ export type ProxyResolutionSource = "explicit" | "env" | "config" | "smartproxy-allocator" | "nodemaven-gateway";
115
116
  export type ResolvedProxyConfig = {
116
117
  shouldWarn: boolean;
117
118
  url?: string;
118
- source?: "explicit" | "env" | "config" | "smartproxy-allocator" | "nodemaven-gateway";
119
+ /** SDK-native vendor that supplied the URL, when applicable. */
120
+ vendor?: ProxyVendorName;
121
+ source?: ProxyResolutionSource;
119
122
  protocol?: ProxyProtocol;
120
123
  diagnostics?: Record<string, string | number | boolean>;
121
124
  };
@@ -142,6 +145,11 @@ export declare function __setProxyRedisForTests(redis: ProxyRedisClient | undefi
142
145
  export declare function __setSmartproxyAllocatorDeadlineMsForTests(deadlineMs: number | undefined): void;
143
146
  export declare function resolveProxyConfig(options?: ProxyResolutionOptions): ResolvedProxyConfig;
144
147
  export declare function resolveProxyConfigAsync(options?: ProxyResolutionOptions): Promise<ResolvedProxyConfig>;
148
+ /**
149
+ * Resolve the proxy URL for a provider-owned consumer such as a CAPTCHA solver.
150
+ * Vendor allocation and failover remain owned by the SDK.
151
+ */
152
+ export declare function resolveProxy(options?: ProxyResolutionOptions): Promise<ResolvedProxyConfig>;
145
153
  /**
146
154
  * Guard the No-MITM invariant: a resolved proxy URL must use a tunnelling scheme
147
155
  * (http CONNECT or socks5) so the client TLS handshake reaches the origin
@@ -400,6 +400,15 @@ export async function resolveProxyConfigAsync(options = {}) {
400
400
  }
401
401
  return { shouldWarn: true };
402
402
  }
403
+ /**
404
+ * Resolve the proxy URL for a provider-owned consumer such as a CAPTCHA solver.
405
+ * Vendor allocation and failover remain owned by the SDK.
406
+ */
407
+ export async function resolveProxy(options = {}) {
408
+ const resolved = await resolveProxyConfigAsync(options);
409
+ const vendor = vendorFromResolvedSource(resolved.source);
410
+ return vendor ? { ...resolved, vendor } : resolved;
411
+ }
403
412
  /**
404
413
  * Each vendor's default egress protocol, chosen from live KR benchmarks. HTTP
405
414
  * CONNECT wins for nodemaven (socks5 adds ~500ms through the gateway) and ties
package/dist/define.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AuthConfig, BrowserEngine, ContextDeclaration, CredentialDeclaration, HealthJourneyDefinition, HealthJourneySchedule, HealthScheduleRandomization, InferSchemaOutput, OperationDefinition, OperationHandlerResult, OperationHttpStreamTransport, OperationSseTransport, OperationWebSocketTransport, ProviderAccessConfig, ProviderDefinition, ProviderDeploymentOverrides, ProviderHealthMonitorConfig, ProviderProxyConfig, ProviderPublicProfile, ProviderReviewed, ProviderSecretDeclaration, ProviderStreamEvent, ProviderSttConfig, SchemaLike, SmsOtpMatcherDefinition, StealthPlatform } from "./types.js";
1
+ import type { AuthConfig, BrowserEngine, ContextDeclaration, CredentialDeclaration, HealthJourneyDefinition, HealthJourneySchedule, HealthScheduleRandomization, InferSchemaOutput, OperationDefinition, OperationHandlerResult, OperationHttpStreamTransport, OperationSseTransport, OperationWebSocketTransport, NativeProviderConfig, ProviderAccessConfig, ProviderDefinition, ProviderDeploymentOverrides, ProviderHealthMonitorConfig, ProviderProxyConfig, ProviderPublicProfile, ProviderReviewed, ProviderSecretDeclaration, ProviderStreamEvent, ProviderSttConfig, SchemaLike, SmsOtpMatcherDefinition, StealthPlatform } from "./types.js";
2
2
  type ProviderImplementationSourceAccess = "official_api" | "private_api" | "browser_flow" | "hybrid";
3
3
  type ProviderImplementationCredentialStrategy = "apifuse_managed" | "workspace_secret" | "user_oauth" | "user_session" | "none";
4
4
  interface ProviderImplementationProfile {
@@ -49,6 +49,7 @@ export interface ProviderConfig<TOperations extends Record<string, ProviderOpera
49
49
  */
50
50
  deployment?: ProviderDeploymentOverrides;
51
51
  allowedHosts?: string[];
52
+ native?: NativeProviderConfig;
52
53
  stealth?: {
53
54
  profile: string;
54
55
  platform: StealthPlatform;
package/dist/define.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import ms from "ms";
2
2
  import { ProviderError, ValidationError } from "./errors.js";
3
3
  import { safeParseSchemaSync } from "./schema.js";
4
+ import { resolveHealthCheckInputDateTokens } from "./server/self-test-input-tokens.js";
4
5
  import { HEALTH_CHECK_DEGRADED_THRESHOLD_MS_MAX, HEALTH_CHECK_DEGRADED_THRESHOLD_MS_MIN, HEALTH_CHECK_TIMEOUT_MS_MAX, HEALTH_CHECK_TIMEOUT_MS_MIN, OPERATION_TIMEOUT_MS_MAX, OPERATION_TIMEOUT_MS_MIN, STREAM_CHUNK_BYTES_MAX, STREAM_CHUNK_BYTES_MIN, STREAM_HEARTBEAT_MS_MAX, STREAM_HEARTBEAT_MS_MIN, STREAM_IDLE_TIMEOUT_MS_MAX, STREAM_IDLE_TIMEOUT_MS_MIN, STREAM_MAX_DURATION_MS_MAX, STREAM_MAX_DURATION_MS_MIN, } from "./types.js";
5
6
  const CONNECTOR_ID_REGEX = /^[a-z][a-z0-9]*(-[a-z][a-z0-9]*)*$/;
6
7
  const OPERATION_ID_REGEX = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/;
@@ -189,7 +190,7 @@ function validateProviderProxy(config) {
189
190
  fix: `Use proxy.session: { affinity: "connection", lifetimeMinutes: 30 }.`,
190
191
  });
191
192
  }
192
- rejectUnknownFields(proxy.session, new Set(["affinity", "lifetimeMinutes", "poolSize"]), "proxy.session");
193
+ rejectUnknownFields(proxy.session, new Set(["affinity", "lifetimeMinutes", "poolSize", "drainLeadSeconds"]), "proxy.session");
193
194
  if (proxy.session.affinity !== undefined) {
194
195
  assertLiteralField(proxy.session.affinity, "proxy.session.affinity", VALID_PROVIDER_PROXY_AFFINITIES, config.id);
195
196
  }
@@ -201,6 +202,24 @@ function validateProviderProxy(config) {
201
202
  if (poolSize !== undefined && (!Number.isInteger(poolSize) || poolSize <= 0)) {
202
203
  throw new ValidationError(`Provider "${config.id}" has invalid proxy.session.poolSize: must be a positive integer.`);
203
204
  }
205
+ const drainLeadSeconds = proxy.session.drainLeadSeconds;
206
+ if (drainLeadSeconds !== undefined &&
207
+ (!Number.isFinite(drainLeadSeconds) || drainLeadSeconds <= 0)) {
208
+ throw new ValidationError(`Provider "${config.id}" has invalid proxy.session.drainLeadSeconds: must be a positive number of seconds.`, {
209
+ fix: `Use proxy.session.drainLeadSeconds: 120 to receive the sticky-expiry drain event 120s before hard expiry.`,
210
+ });
211
+ }
212
+ // A drain lead longer than the sticky lifetime would fire the expiring
213
+ // event before the session is even established, so the provider would
214
+ // never get a usable window. Reject the contradiction at build time.
215
+ if (drainLeadSeconds !== undefined &&
216
+ lifetime !== undefined &&
217
+ Number.isFinite(lifetime) &&
218
+ drainLeadSeconds >= lifetime * 60) {
219
+ throw new ValidationError(`Provider "${config.id}" has proxy.session.drainLeadSeconds (${drainLeadSeconds}s) greater than or equal to proxy.session.lifetimeMinutes (${lifetime}m).`, {
220
+ fix: `Lower drainLeadSeconds below the sticky lifetime so the drain event leaves a usable session window.`,
221
+ });
222
+ }
204
223
  }
205
224
  // Every credentialed vendor in a required-mode chain must declare its
206
225
  // provider secret(s) so a missing credential fails at build/validation time,
@@ -1294,6 +1313,21 @@ function validateOperationFixtures(providerId, operations) {
1294
1313
  throw new ValidationError(`Operation handler must be defined for provider "${providerId}" operation "${operationName}"`, {
1295
1314
  fix: `Add operations.${operationName}.handler as an async function with signature (ctx, input) => Promise<output>`,
1296
1315
  });
1316
+ if (operation.fixtures?.recordedAt !== undefined) {
1317
+ const recordedAt = operation.fixtures.recordedAt;
1318
+ const parsed = typeof recordedAt === "string"
1319
+ ? new Date(`${recordedAt}T00:00:00.000Z`)
1320
+ : new Date(Number.NaN);
1321
+ const isCalendarDate = typeof recordedAt === "string" &&
1322
+ /^\d{4}-\d{2}-\d{2}$/.test(recordedAt) &&
1323
+ !Number.isNaN(parsed.getTime()) &&
1324
+ parsed.toISOString().slice(0, 10) === recordedAt;
1325
+ const kstToday = new Date(Date.now() + 9 * 60 * 60 * 1000).toISOString().slice(0, 10);
1326
+ if (!isCalendarDate || recordedAt > kstToday)
1327
+ throw new ValidationError(`Fixture recordedAt must be a valid, non-future KST calendar date for provider "${providerId}" operation "${operationName}"`, {
1328
+ fix: `Set operations.${operationName}.fixtures.recordedAt to the KST capture date in YYYY-MM-DD format; it must not be in the future.`,
1329
+ });
1330
+ }
1297
1331
  if (operation.fixtures?.request !== undefined) {
1298
1332
  const result = safeParseSchemaSync(operation.input, operation.fixtures.request, `operations.${operationName}.fixtures.request`);
1299
1333
  if (!result.success)
@@ -1312,6 +1346,28 @@ function validateOperationFixtures(providerId, operations) {
1312
1346
  }
1313
1347
  }
1314
1348
  }
1349
+ function resolveOperationFixtureRequests(operations) {
1350
+ let changed = false;
1351
+ const resolvedOperations = Object.fromEntries(Object.entries(operations).map(([operationName, operation]) => {
1352
+ if (operation.fixtures?.request === undefined)
1353
+ return [operationName, operation];
1354
+ const request = resolveHealthCheckInputDateTokens(operation.fixtures.request);
1355
+ if (request === operation.fixtures.request)
1356
+ return [operationName, operation];
1357
+ changed = true;
1358
+ return [
1359
+ operationName,
1360
+ {
1361
+ ...operation,
1362
+ fixtures: {
1363
+ ...operation.fixtures,
1364
+ request,
1365
+ },
1366
+ },
1367
+ ];
1368
+ }));
1369
+ return changed ? resolvedOperations : operations;
1370
+ }
1315
1371
  /**
1316
1372
  * Shallow shape guard only: the `deployment` object is passed through
1317
1373
  * verbatim and deliberately not deep-validated by the SDK — the APIFuse
@@ -1327,6 +1383,7 @@ function validateProviderDeployment(providerId, deployment) {
1327
1383
  }
1328
1384
  export function defineProvider(config) {
1329
1385
  validateProviderShape(config);
1386
+ const operations = resolveOperationFixtureRequests(config.operations);
1330
1387
  if (!CONNECTOR_ID_REGEX.test(config.id))
1331
1388
  throw new ProviderError(`Invalid provider id: "${config.id}"`, {
1332
1389
  fix: 'Use lowercase alphanumeric with dashes, e.g., "korea-air-quality"',
@@ -1348,7 +1405,7 @@ export function defineProvider(config) {
1348
1405
  fix: "Keep healthProbe (the new name) and delete the healthMonitor block.",
1349
1406
  });
1350
1407
  validateProviderHealthMonitor(config.id, config.healthProbe ?? config.healthMonitor, config.healthProbe !== undefined ? "healthProbe" : "healthMonitor");
1351
- validateOperationFixtures(config.id, config.operations);
1408
+ validateOperationFixtures(config.id, operations);
1352
1409
  validateProviderDeployment(config.id, config.deployment);
1353
1410
  validateProviderProxy(config);
1354
1411
  validateProviderStt(config);
@@ -1366,6 +1423,7 @@ export function defineProvider(config) {
1366
1423
  // are owned by the APIFuse registry builder, not the SDK.
1367
1424
  deployment: config.deployment,
1368
1425
  allowedHosts: config.allowedHosts,
1426
+ native: config.native,
1369
1427
  stealth: config.stealth,
1370
1428
  proxy: config.proxy,
1371
1429
  stt: config.stt,
@@ -1377,7 +1435,7 @@ export function defineProvider(config) {
1377
1435
  credential: config.credential,
1378
1436
  context: config.context,
1379
1437
  meta: config.meta,
1380
- operations: config.operations,
1438
+ operations,
1381
1439
  // Transitional healthMonitor → healthProbe alias: mirror whichever field
1382
1440
  // was declared onto both so old and new consumers keep working.
1383
1441
  healthMonitor: config.healthMonitor ?? config.healthProbe,
package/dist/errors.d.ts CHANGED
@@ -17,6 +17,11 @@ export declare class ProviderError extends Error {
17
17
  export declare class SDKError extends ProviderError {
18
18
  constructor(message: string, options?: ProviderErrorOptions);
19
19
  }
20
+ /** Raised when persisted stealth cookies use a store version this SDK cannot read. */
21
+ export declare class StealthCookieStoreVersionError extends SDKError {
22
+ readonly version: unknown;
23
+ constructor(version: unknown);
24
+ }
20
25
  export declare class AuthError extends ProviderError {
21
26
  constructor(message: string, options?: ProviderErrorOptions);
22
27
  }
package/dist/errors.js CHANGED
@@ -57,6 +57,21 @@ export class SDKError extends ProviderError {
57
57
  this.name = "SDKError";
58
58
  }
59
59
  }
60
+ /** Raised when persisted stealth cookies use a store version this SDK cannot read. */
61
+ export class StealthCookieStoreVersionError extends SDKError {
62
+ version;
63
+ constructor(version) {
64
+ const displayedVersion = typeof version === "string" || typeof version === "number"
65
+ ? String(version)
66
+ : "missing or invalid";
67
+ super(`Unsupported stealth cookie store version: ${displayedVersion}`, {
68
+ code: "unsupported_stealth_cookie_store_version",
69
+ details: { receivedVersion: version, supportedVersions: [1] },
70
+ });
71
+ this.version = version;
72
+ this.name = "StealthCookieStoreVersionError";
73
+ }
74
+ }
60
75
  export class AuthError extends ProviderError {
61
76
  constructor(message, options) {
62
77
  super(message, options);
@@ -0,0 +1,26 @@
1
+ import type { JsonValue } from "./contract-json.js";
2
+ export declare const REDACTED_FIXTURE_VALUE = "[REDACTED]";
3
+ /** Matches credential field names without treating benign prefixes such as `author` as `auth`. */
4
+ export declare function isSensitiveFixtureKey(key: string): boolean;
5
+ /**
6
+ * Returns JSON fixture data with credential-bearing keys and heuristic-confirmed string secrets
7
+ * replaced. Ordinary short prose and identifiers are retained.
8
+ */
9
+ export declare function sanitizeFixture(value: JsonValue): JsonValue;
10
+ /** Applies the shared credential-key policy to ordinary JSON fixtures. */
11
+ export declare function sanitizeOrdinaryFixture(value: JsonValue): JsonValue;
12
+ /** Sanitizes a primitive fixture string only when textual-secret heuristics match. */
13
+ export declare function sanitizeFixtureString(value: string): string;
14
+ /** True for opaque values that are unsafe to retain in paths or unstructured text. */
15
+ export declare function isSensitiveFixtureValue(value: string): boolean;
16
+ /** Sanitizes every path segment and values following a credential-like segment name. */
17
+ export declare function sanitizePathname(pathname: string): string;
18
+ /** Removes userinfo, query values, fragments, and credential-like path segments from log URLs. */
19
+ export declare function sanitizeUrlForLogs(value: string): string;
20
+ /**
21
+ * Returns query-free request provenance with each path segment scrubbed for credential-like values.
22
+ * Origins, URL userinfo, query values, and fragments are never persisted in request provenance.
23
+ */
24
+ export declare function requestPathForFixture(value: string): string;
25
+ /** Scrubs secrets and terminal/log control characters before diagnostic text is emitted. */
26
+ export declare function sanitizeDiagnosticText(value: string): string;
@@ -0,0 +1,216 @@
1
+ export const REDACTED_FIXTURE_VALUE = "[REDACTED]";
2
+ const OPAQUE_TOKEN = /^[A-Za-z0-9_+/=.:~-]+$/;
3
+ const OPAQUE_TOKEN_RUN = /[A-Za-z0-9_+/=.:~-]{24,}/g;
4
+ const URL_RUN = /https?:\/\/[^\s"'<>]+/gi;
5
+ const PEM_PRIVATE_KEY = /-----BEGIN (?:[A-Z0-9 ]+ )?PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z0-9 ]+ )?PRIVATE KEY-----/g;
6
+ /** Matches credential field names without treating benign prefixes such as `author` as `auth`. */
7
+ export function isSensitiveFixtureKey(key) {
8
+ const normalized = key.replace(/[-_\s]/g, "").toLowerCase();
9
+ const candidates = [normalized, normalized.replace(/(?:value|payload|header)$/, "")];
10
+ return candidates.some((candidate) => /^(?:authorization|authentication|auth|bearer|cookie|credential|password|passwd|privatekey|secret|session|sessionid|token)$/.test(candidate) ||
11
+ /^(?:api|client|service|access|consumer)(?:key|secret|token)$/.test(candidate) ||
12
+ /(?:authorization|credential|password|passwd|privatekey|secret|sessionid|token)$/.test(candidate));
13
+ }
14
+ /**
15
+ * Returns JSON fixture data with credential-bearing keys and heuristic-confirmed string secrets
16
+ * replaced. Ordinary short prose and identifiers are retained.
17
+ */
18
+ export function sanitizeFixture(value) {
19
+ if (Array.isArray(value)) {
20
+ return value.map((item) => sanitizeFixture(item));
21
+ }
22
+ if (typeof value === "string")
23
+ return sanitizeFixtureString(value);
24
+ if (value === null || typeof value !== "object")
25
+ return value;
26
+ return Object.fromEntries(Object.entries(value).map(([key, entryValue]) => [
27
+ key,
28
+ isSensitiveFixtureKey(key) ? REDACTED_FIXTURE_VALUE : sanitizeFixture(entryValue),
29
+ ]));
30
+ }
31
+ /** Applies the shared credential-key policy to ordinary JSON fixtures. */
32
+ export function sanitizeOrdinaryFixture(value) {
33
+ if (Array.isArray(value))
34
+ return value.map((item) => sanitizeOrdinaryFixture(item));
35
+ if (value === null || typeof value !== "object")
36
+ return value;
37
+ return Object.fromEntries(Object.entries(value).map(([key, entryValue]) => [
38
+ key,
39
+ isSensitiveFixtureKey(key) ? REDACTED_FIXTURE_VALUE : sanitizeOrdinaryFixture(entryValue),
40
+ ]));
41
+ }
42
+ /** Sanitizes a primitive fixture string only when textual-secret heuristics match. */
43
+ export function sanitizeFixtureString(value) {
44
+ let sanitized = value.replace(PEM_PRIVATE_KEY, REDACTED_FIXTURE_VALUE);
45
+ const retainedUrls = [];
46
+ sanitized = sanitized.replace(URL_RUN, (url) => {
47
+ const index = retainedUrls.push(isCredentialBearingUrl(url) ? sanitizeUrlForLogs(url) : url) - 1;
48
+ return `APIFUSEURL${index}X`;
49
+ });
50
+ sanitized = redactSensitiveAssignments(sanitized);
51
+ sanitized = sanitized.replace(OPAQUE_TOKEN_RUN, (candidate) => isSensitiveFixtureValue(candidate) ? REDACTED_FIXTURE_VALUE : candidate);
52
+ sanitized = sanitized.replace(/APIFUSEURL(\d+)X/g, (_match, index) => retainedUrls[Number(index)] ?? REDACTED_FIXTURE_VALUE);
53
+ return sanitized;
54
+ }
55
+ /** True for opaque values that are unsafe to retain in paths or unstructured text. */
56
+ export function isSensitiveFixtureValue(value) {
57
+ const candidate = decodePathSegment(value);
58
+ if (/^bot(?:\d{6,}:)?[A-Za-z0-9_-]{16,}$/i.test(candidate))
59
+ return true;
60
+ if (/^\d{6,}:[A-Za-z0-9_-]{20,}$/.test(candidate))
61
+ return true;
62
+ if (/^(?:gh[opusr]_|sk[-_]|xox[baprs]-)[A-Za-z0-9_-]{16,}$/i.test(candidate))
63
+ return true;
64
+ if (!OPAQUE_TOKEN.test(candidate) || candidate.length < 24)
65
+ return false;
66
+ if (/^[a-f0-9]{32,}$/i.test(candidate))
67
+ return true;
68
+ return shannonEntropy(candidate) >= 3.5;
69
+ }
70
+ /** Sanitizes every path segment and values following a credential-like segment name. */
71
+ export function sanitizePathname(pathname) {
72
+ const segments = pathname.split("/");
73
+ return segments
74
+ .map((segment, index) => {
75
+ if (!segment)
76
+ return segment;
77
+ const decoded = decodePathSegment(segment);
78
+ const previous = index > 0 ? decodePathSegment(segments[index - 1]) : "";
79
+ if (isSensitivePathSegment(decoded) ||
80
+ isCredentialPathKey(previous) ||
81
+ isSensitiveFixtureValue(decoded)) {
82
+ return REDACTED_FIXTURE_VALUE;
83
+ }
84
+ return segment;
85
+ })
86
+ .join("/");
87
+ }
88
+ function isCredentialPathKey(key) {
89
+ const finalPathPart = key.split("/").at(-1) ?? "";
90
+ const baseSegment = finalPathPart.split(";", 1)[0] ?? "";
91
+ return isSensitiveFixtureKey(baseSegment.split(/[=:]/, 1)[0] ?? "");
92
+ }
93
+ function isSensitivePathSegment(segment) {
94
+ return segment
95
+ .split(/[;/]/)
96
+ .some((part) => isSensitiveFixtureKey(part.split(/[=:]/, 1)[0] ?? ""));
97
+ }
98
+ /** Removes userinfo, query values, fragments, and credential-like path segments from log URLs. */
99
+ export function sanitizeUrlForLogs(value) {
100
+ try {
101
+ const parsed = new URL(value, "https://fixture.invalid");
102
+ const queryMarker = parsed.search ? `?${REDACTED_FIXTURE_VALUE}` : "";
103
+ const path = sanitizePathname(parsed.pathname);
104
+ if (parsed.origin === "https://fixture.invalid" && !hasExplicitOrigin(value)) {
105
+ return `${path}${queryMarker}`;
106
+ }
107
+ return `${parsed.origin}${path}${queryMarker}`;
108
+ }
109
+ catch {
110
+ return sanitizePathname(value.split(/[?#]/, 1)[0]);
111
+ }
112
+ }
113
+ /**
114
+ * Returns query-free request provenance with each path segment scrubbed for credential-like values.
115
+ * Origins, URL userinfo, query values, and fragments are never persisted in request provenance.
116
+ */
117
+ export function requestPathForFixture(value) {
118
+ try {
119
+ return sanitizePathname(new URL(value, "https://fixture.invalid").pathname);
120
+ }
121
+ catch {
122
+ const path = value.split(/[?#]/, 1)[0];
123
+ return sanitizePathname(path.startsWith("/") ? path : `/${path}`);
124
+ }
125
+ }
126
+ /** Scrubs secrets and terminal/log control characters before diagnostic text is emitted. */
127
+ export function sanitizeDiagnosticText(value) {
128
+ let sanitized = value
129
+ .replace(URL_RUN, (url) => sanitizeUrlForLogs(url))
130
+ .replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/gi, `Bearer ${REDACTED_FIXTURE_VALUE}`);
131
+ sanitized = redactSensitiveAssignments(sanitized);
132
+ sanitized = sanitized.replace(OPAQUE_TOKEN_RUN, (candidate, offset, source) => {
133
+ if (/^(?:request|trace|correlation)[-_]?id[:=]/i.test(candidate))
134
+ return candidate;
135
+ const prefix = source.slice(Math.max(0, offset - 32), offset);
136
+ if (/(?:request|trace|correlation)[-_]?id\s*[:=]\s*$/i.test(prefix))
137
+ return candidate;
138
+ return isSensitiveFixtureValue(candidate) ? REDACTED_FIXTURE_VALUE : candidate;
139
+ });
140
+ return encodeDiagnosticControls(sanitized);
141
+ }
142
+ function redactSensitiveAssignments(value) {
143
+ return value.replace(/((["']?)([\w-]+)\2\s*[:=]\s*)("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;&]+)/gi, (match, prefix, _quote, key, assignmentValue) => {
144
+ if (!isSensitiveFixtureKey(key) && key.toLowerCase() !== "key")
145
+ return match;
146
+ const quote = assignmentValue.startsWith('"')
147
+ ? '"'
148
+ : assignmentValue.startsWith("'")
149
+ ? "'"
150
+ : "";
151
+ return `${prefix}${quote}${REDACTED_FIXTURE_VALUE}${quote}`;
152
+ });
153
+ }
154
+ function isCredentialBearingUrl(value) {
155
+ try {
156
+ const parsed = new URL(value);
157
+ return (parsed.username !== "" ||
158
+ parsed.password !== "" ||
159
+ parsed.hash !== "" ||
160
+ parsed.search !== "" ||
161
+ parsed.pathname.split("/").some((segment, index, segments) => {
162
+ const decoded = decodePathSegment(segment);
163
+ const previous = decodePathSegment(segments[index - 1] ?? "");
164
+ return (isSensitiveFixtureKey(decoded) ||
165
+ isCredentialPathKey(previous) ||
166
+ isSensitiveFixtureValue(decoded));
167
+ }));
168
+ }
169
+ catch {
170
+ return false;
171
+ }
172
+ }
173
+ function encodeDiagnosticControls(value) {
174
+ let result = "";
175
+ for (const character of value) {
176
+ const code = character.codePointAt(0) ?? 0;
177
+ if (code === 0x0a || code === 0x0d || code === 0x2028 || code === 0x2029) {
178
+ result += " ";
179
+ }
180
+ else if ((code >= 0 && code <= 0x1f) ||
181
+ (code >= 0x7f && code <= 0x9f) ||
182
+ code === 0x061c ||
183
+ code === 0x200e ||
184
+ code === 0x200f ||
185
+ (code >= 0x202a && code <= 0x202e) ||
186
+ (code >= 0x2066 && code <= 0x2069)) {
187
+ result += `\\u${code.toString(16).padStart(4, "0")}`;
188
+ }
189
+ else {
190
+ result += character;
191
+ }
192
+ }
193
+ return result;
194
+ }
195
+ function decodePathSegment(value) {
196
+ try {
197
+ return decodeURIComponent(value);
198
+ }
199
+ catch {
200
+ return value;
201
+ }
202
+ }
203
+ function hasExplicitOrigin(value) {
204
+ return /^[a-z][a-z\d+.-]*:\/\//i.test(value);
205
+ }
206
+ function shannonEntropy(value) {
207
+ const counts = new Map();
208
+ for (const character of value)
209
+ counts.set(character, (counts.get(character) ?? 0) + 1);
210
+ let entropy = 0;
211
+ for (const count of counts.values()) {
212
+ const probability = count / value.length;
213
+ entropy -= probability * Math.log2(probability);
214
+ }
215
+ return entropy;
216
+ }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export * from "./auth.js";
2
2
  export * from "./ceremonies/index.js";
3
3
  export * from "./choice-token.js";
4
- export type { ApiFuseConfig, BrowserConfig, ProxyConfig, SessionConfig, } from "./config/loader.js";
5
- export { defineConfig, loadApiFuseConfig } from "./config/loader.js";
4
+ export type { ApiFuseConfig, BrowserConfig, ProxyConfig, ProxyProtocol, ProxyResolutionOptions, ProxyResolutionSource, ProxyVendorName, ResolvedProxyConfig, SessionConfig, } from "./config/loader.js";
5
+ export { defineConfig, loadApiFuseConfig, resolveProxy } from "./config/loader.js";
6
6
  export { canonicalJson, digestProviderContract, extractProviderContract, type JsonPrimitive, type JsonValue, PROVIDER_CONTRACT_SCHEMA_VERSION, type ProviderContractOperation, type ProviderContractSnapshot, } from "./contract.js";
7
7
  export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, defineStreamOperation, every, type ProviderConfig, } from "./define.js";
8
8
  export type { DevServerOptions } from "./dev.js";
@@ -22,6 +22,7 @@ export { type CreateCredentialContextOptions, createCredentialContext, } from ".
22
22
  export { createEnvContext } from "./runtime/env.js";
23
23
  export { executeOperation } from "./runtime/executor.js";
24
24
  export { createHttpClient } from "./runtime/http.js";
25
+ export { createNativeNetworkClient, deriveNativeCredentialAffinityKey, NativeIdleTimeoutError, NativeNetworkError, NativeProxyExpiredError, resolveNativeGatewayProxy, type NativeGatewayProxy, type NativeGatewayProxyResolutionInput, type NativeGatewayProxySynthesizer, type NativeGatewayProxySynthesisInput, type NativeNetworkClientOptions, type NativeNetworkErrorCode, } from "./runtime/native-network.js";
25
26
  export type { Insight, InsightSeverity } from "./runtime/insights.js";
26
27
  export { generateInsights } from "./runtime/insights.js";
27
28
  export { type InstrumentationOptions, type InstrumentedProviderContext, wrapWithInstrumentation, } from "./runtime/instrumentation.js";
@@ -36,7 +37,7 @@ export { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SEN
36
37
  export { createServerApp, type ServeOptions, serve } from "./server/index.js";
37
38
  export { getStealthProfile, listStealthProfiles } from "./stealth/profiles.js";
38
39
  export * from "./stream.js";
39
- export type { ApiFuseResponse, AuthConfig, AuthContext, AuthFlowDefinition, AuthFlowInputHandler, AuthFlowStartHandler, AuthMode, AuthTurn, Bcp47Locale, BrowserEngine, BrowserOptions, BrowserResourceBody, BrowserResourceDecision, BrowserResourceMethod, BrowserResourcePolicy, BrowserResourceRequest, BrowserResourceRoute, ConnectionMode, ContextDeclaration, CookieJar, ContextScratchpad, CredentialContext, CredentialDeclaration, E164PhoneNumber, EnvContext, FlowContext, FlowContextStore, HealthCheckAssertionContext, HealthCheckCase, HealthCheckCaseResult, HealthCheckSuite, HealthCheckUnsupported, HealthJourneyDefinition, HealthJourneyEventContext, HealthJourneyGatewayContext, HealthJourneyJournalContext, HealthJourneyManualTriggerPolicy, HealthJourneyRunContext, HealthJourneyRunResult, HealthJourneySchedule, HealthScheduleRandomization, HealthJourneySmsContext, HealthJourneyStep, HttpClient, HttpMethod, HttpResponse, HttpRetryOptions, HttpRetrySummary, HttpStreamResponse, IanaTimeZone, InferSchemaOutput, Iso3166Alpha2CountryCode, Iso4217CurrencyCode, Iso8601Duration, OperationAnnotations, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationDeprecationMetadata, OperationDocMeta, OperationErrorCode, OperationHandlerResult, OperationInputExample, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationToolRouterMetadata, OperationTransport, OperationTransportKind, ProbeInterval, ProviderAccessConfig, ProviderAccessVisibility, ProviderCache, ProviderCacheGetOrSetOptions, ProviderCacheKeyOptions, ProviderCacheLookupMeta, ProviderCacheResponseMeta, ProviderCacheResult, ProviderChoiceBindingOptions, ProviderChoiceContext, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderContext, ProviderDefinition, ProviderDeploymentOverrides, ProviderHealthMonitorConfig, ProviderHealthProbeConfig, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderLogoSource, ProviderMeta, ProviderProxyConfig, ProviderProxyMode, ProviderProxyPolicy, ProviderProxyProvider, ProviderProxySessionAffinity, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderReviewed, ProviderRuntimeState, ProviderSecretDeclaration, ProviderStateDurationString, ProviderStateNamespace, ProviderStreamEvent, ProviderSttConfig, ProviderSttMode, ProviderSupportLevel, RequestOptions, Rfc3339Instant, SchemaLike, SmsOrigin, SmsOtpExtractionPattern, SmsOtpMatcherDefinition, SseMessage, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateValue, StateWriteOptions, StealthClient, StealthFetchOptions, StealthPlatform, StealthProfile, StealthRedirectHop, StealthRedirectRunOptions, StealthRedirectRunResult, StealthResponse, StealthSession, StealthSessionCookies, SttAudioInput, SttContext, SttPromptPolicy, SttSegment, SttTranscribeMode, SttTranscribeRequest, SttTranscript, SttUnsupportedOptionPolicy, SttUsage, SttVerificationCodeOptions, SttWarning, TraceConfig, TraceSpan, VerificationCodeCandidate, VerificationCodeCandidateSource, VerificationCodeExtractionResult, } from "./types.js";
40
+ export type { ApiFuseResponse, AuthConfig, AuthContext, AuthFlowDefinition, AuthFlowInputHandler, AuthFlowStartHandler, AuthMode, AuthTurn, Bcp47Locale, BrowserEngine, BrowserOptions, BrowserResourceBody, BrowserResourceDecision, BrowserResourceMethod, BrowserResourcePolicy, BrowserResourceRequest, BrowserResourceRoute, ConnectionMode, ContextDeclaration, CookieJar, ContextScratchpad, CredentialContext, CredentialDeclaration, E164PhoneNumber, EnvContext, FlowContext, FlowContextStore, HealthCheckAssertionContext, HealthCheckCase, HealthCheckCaseResult, HealthCheckSuite, HealthCheckUnsupported, HealthJourneyDefinition, HealthJourneyEventContext, HealthJourneyGatewayContext, HealthJourneyJournalContext, HealthJourneyManualTriggerPolicy, HealthJourneyRunContext, HealthJourneyRunResult, HealthJourneySchedule, HealthScheduleRandomization, HealthJourneySmsContext, HealthJourneyStep, HttpClient, HttpMethod, HttpResponse, HttpRetryOptions, HttpRetrySummary, HttpStreamResponse, IanaTimeZone, InferSchemaOutput, Iso3166Alpha2CountryCode, Iso4217CurrencyCode, Iso8601Duration, NativeContext, NativeNetworkClient, NativeNetworkCloseReason, NativeNetworkConnection, NativeNetworkConnectInput, NativeNetworkConnectOptions, NativeNetworkDynamicGrantOptions, NativeNetworkEgressGrant, NativeProviderConfig, NativeProviderContext, NativeProxyDrainHandler, NativeProxyEgressInfo, NativeProxyExpiringEvent, NativeProxyExpiringReason, NativeTcpDynamicEgressRule, NativeTcpEgressGrant, NativeTcpEgressRule, NativeTcpPortRange, NativeTcpTlsMode, NativeTlsConnectOptions, OperationAnnotations, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationDeprecationMetadata, OperationDocMeta, OperationErrorCode, OperationHandlerResult, OperationInputExample, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationToolRouterMetadata, OperationTransport, OperationTransportKind, ProbeInterval, ProviderAccessConfig, ProviderAccessVisibility, ProviderCache, ProviderCacheGetOrSetOptions, ProviderCacheKeyOptions, ProviderCacheLookupMeta, ProviderCacheResponseMeta, ProviderCacheResult, ProviderChoiceBindingOptions, ProviderChoiceContext, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderContext, ProviderDefinition, ProviderDeploymentOverrides, ProviderFileRef, ProviderFilesContext, ProviderHealthMonitorConfig, ProviderHealthProbeConfig, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderLogoSource, ProviderMeta, ProviderProxyConfig, ProviderProxyMode, ProviderProxyPolicy, ProviderProxyProvider, ProviderProxySessionAffinity, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderReviewed, ProviderResolvedFile, ProviderRuntimeState, ProviderSecretDeclaration, ProviderStateDurationString, ProviderStateNamespace, ProviderStreamEvent, ProviderSttConfig, ProviderSttMode, ProviderSupportLevel, RequestOptions, Rfc3339Instant, SchemaLike, SmsOrigin, SmsOtpExtractionPattern, SmsOtpMatcherDefinition, SseMessage, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateValue, StateWriteOptions, StealthClient, StealthCookieStore, StealthCookieStoreV1, StealthFetchOptions, StealthPlatform, StealthProfile, StealthRedirectHop, StealthRedirectRunOptions, StealthRedirectRunResult, StealthResponse, StealthSession, StealthSessionCookies, SttAudioInput, SttContext, SttPromptPolicy, SttSegment, SttTranscribeMode, SttTranscribeRequest, SttTranscript, SttUnsupportedOptionPolicy, SttUsage, SttVerificationCodeOptions, SttWarning, TraceConfig, TraceSpan, VerificationCodeCandidate, VerificationCodeCandidateSource, VerificationCodeExtractionResult, } from "./types.js";
40
41
  export { DEFAULT_OPERATION_TRANSPORT, HttpRetryAfterPolicy, HttpRetryDelayStrategy, HttpRetryJitter, HttpRetryPreset, HttpRetryUnsafeMethodPolicy, PROBE_INTERVALS, STREAM_CHUNK_BYTES_MAX, STREAM_CHUNK_BYTES_MIN, STREAM_HEARTBEAT_MS_MAX, STREAM_HEARTBEAT_MS_MIN, STREAM_IDLE_TIMEOUT_MS_MAX, STREAM_IDLE_TIMEOUT_MS_MIN, STREAM_MAX_DURATION_MS_MAX, STREAM_MAX_DURATION_MS_MIN, } from "./types.js";
41
42
  export * from "./utils/date.js";
42
43
  export * from "./utils/parse.js";
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  export * from "./auth.js";
3
3
  export * from "./ceremonies/index.js";
4
4
  export * from "./choice-token.js";
5
- export { defineConfig, loadApiFuseConfig } from "./config/loader.js";
5
+ export { defineConfig, loadApiFuseConfig, resolveProxy } from "./config/loader.js";
6
6
  export { canonicalJson, digestProviderContract, extractProviderContract, PROVIDER_CONTRACT_SCHEMA_VERSION, } from "./contract.js";
7
7
  export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, defineStreamOperation, every, } from "./define.js";
8
8
  export { createDevServer, startDevServer } from "./dev.js";
@@ -20,6 +20,7 @@ export { createCredentialContext, } from "./runtime/credential.js";
20
20
  export { createEnvContext } from "./runtime/env.js";
21
21
  export { executeOperation } from "./runtime/executor.js";
22
22
  export { createHttpClient } from "./runtime/http.js";
23
+ export { createNativeNetworkClient, deriveNativeCredentialAffinityKey, NativeIdleTimeoutError, NativeNetworkError, NativeProxyExpiredError, resolveNativeGatewayProxy, } from "./runtime/native-network.js";
23
24
  export { generateInsights } from "./runtime/insights.js";
24
25
  export { wrapWithInstrumentation, } from "./runtime/instrumentation.js";
25
26
  export { prevalidate } from "./runtime/prevalidate.js";
@@ -7,5 +7,6 @@ export { AuthError, isProviderError, isSessionExpiredError, isTransportError, Pr
7
7
  export { getProviderLocalePath, providerLocaleKey, qualifyProviderLocaleKey, } from "./i18n/index.js";
8
8
  export { type CreateProviderChoiceContextOptions, createProviderChoiceContext, createTestProviderChoiceContext, PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV, } from "./runtime/choice.js";
9
9
  export { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, redactPayload, type SensitiveFieldKind, type SensitiveFieldOptions, type SensitivePath, sensitive, z, } from "./schema.js";
10
- export type { AuthAbortData, AuthAbortRetry, AuthFlowTerminalContext, AuthMode, AuthSafeData, AuthSafeJson, FlowContext, HealthCheckAssertionContext, HealthCheckCase, HealthCheckSuite, HealthCheckUnsupported, HealthJourneyDefinition, HealthJourneyEventContext, HealthJourneyManualTriggerPolicy, HealthJourneyRunContext, HealthJourneyRunResult, HealthScheduleRandomization, HttpRetryOptions, HttpRetrySummary, InferSchemaOutput, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationDocMeta, OperationErrorCode, OperationInputExample, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationToolRouterMetadata, OperationTransport, ProviderAccessVisibility, ProviderChoiceBindingOptions, ProviderChoiceContext, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderContext, ProviderDefinition, ProviderDeploymentOverrides, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderProxyPolicy, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderRuntimeState, ProviderStateDurationString, ProviderStateNamespace, ProviderSupportLevel, SchemaLike, SmsOtpMatcherDefinition, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateValue, StateWriteOptions, } from "./types.js";
10
+ export type { AuthAbortData, AuthAbortRetry, AuthFlowTerminalContext, AuthMode, AuthSafeData, AuthSafeJson, FlowContext, HealthCheckAssertionContext, HealthCheckCase, HealthCheckSuite, HealthCheckUnsupported, HealthJourneyDefinition, HealthJourneyEventContext, HealthJourneyManualTriggerPolicy, HealthJourneyRunContext, HealthJourneyRunResult, HealthScheduleRandomization, HttpRetryOptions, HttpRetrySummary, InferSchemaOutput, NativeContext, NativeNetworkClient, NativeNetworkCloseReason, NativeNetworkConnection, NativeNetworkConnectInput, NativeNetworkConnectOptions, NativeNetworkDynamicGrantOptions, NativeNetworkEgressGrant, NativeProviderConfig, NativeProviderContext, NativeProxyDrainHandler, NativeProxyEgressInfo, NativeProxyExpiringEvent, NativeProxyExpiringReason, NativeTcpDynamicEgressRule, NativeTcpEgressGrant, NativeTcpEgressRule, NativeTcpPortRange, NativeTcpTlsMode, NativeTlsConnectOptions, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationDocMeta, OperationErrorCode, OperationInputExample, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationToolRouterMetadata, OperationTransport, ProviderAccessVisibility, ProviderChoiceBindingOptions, ProviderChoiceContext, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderContext, ProviderDefinition, ProviderDeploymentOverrides, ProviderFileRef, ProviderFilesContext, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderProxyPolicy, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderResolvedFile, ProviderRuntimeState, ProviderStateDurationString, ProviderStateNamespace, ProviderSupportLevel, SchemaLike, SmsOtpMatcherDefinition, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateValue, StateWriteOptions, } from "./types.js";
11
+ export { createNativeNetworkClient, deriveNativeCredentialAffinityKey, NativeIdleTimeoutError, NativeNetworkError, NativeProxyExpiredError, resolveNativeGatewayProxy, type NativeGatewayProxy, type NativeGatewayProxyResolutionInput, type NativeGatewayProxySynthesizer, type NativeGatewayProxySynthesisInput, type NativeNetworkClientOptions, type NativeNetworkErrorCode, } from "./runtime/native-network.js";
11
12
  export { HttpRetryAfterPolicy, HttpRetryDelayStrategy, HttpRetryJitter, HttpRetryPreset, HttpRetryUnsafeMethodPolicy, } from "./types.js";
package/dist/provider.js CHANGED
@@ -6,4 +6,5 @@ export { AuthError, isProviderError, isSessionExpiredError, isTransportError, Pr
6
6
  export { getProviderLocalePath, providerLocaleKey, qualifyProviderLocaleKey, } from "./i18n/index.js";
7
7
  export { createProviderChoiceContext, createTestProviderChoiceContext, PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV, } from "./runtime/choice.js";
8
8
  export { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, redactPayload, sensitive, z, } from "./schema.js";
9
+ export { createNativeNetworkClient, deriveNativeCredentialAffinityKey, NativeIdleTimeoutError, NativeNetworkError, NativeProxyExpiredError, resolveNativeGatewayProxy, } from "./runtime/native-network.js";
9
10
  export { HttpRetryAfterPolicy, HttpRetryDelayStrategy, HttpRetryJitter, HttpRetryPreset, HttpRetryUnsafeMethodPolicy, } from "./types.js";