@apifuse/provider-sdk 2.2.0-beta.16 → 2.2.0-beta.18

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.
@@ -8,6 +8,12 @@ export const NODEMAVEN_FILTER_ENV = "APIFUSE__PROXY__NODEMAVEN_FILTER";
8
8
 
9
9
  export const NODEMAVEN_GATEWAY_HOST = "gate.nodemaven.com";
10
10
 
11
+ export type NodemavenCredentials = {
12
+ readonly username: string;
13
+ readonly password: string;
14
+ readonly filter?: string;
15
+ };
16
+
11
17
  /** Both schemes tunnel bytes end-to-end, preserving the client TLS handshake. */
12
18
  export type ProxyProtocol = "http" | "socks5";
13
19
 
@@ -44,8 +50,8 @@ function readNodemavenPassword(): string | undefined {
44
50
  return process.env[NODEMAVEN_PASSWORD_ENV]?.trim() || undefined;
45
51
  }
46
52
 
47
- function resolveNodemavenFilter(): string {
48
- const raw = process.env[NODEMAVEN_FILTER_ENV]?.trim().toLowerCase();
53
+ function resolveNodemavenFilter(value: string | undefined): string {
54
+ const raw = value?.trim().toLowerCase();
49
55
  if (!raw) return DEFAULT_NODEMAVEN_FILTER;
50
56
  if (!NODEMAVEN_FILTERS.has(raw)) {
51
57
  throw new Error(`${NODEMAVEN_FILTER_ENV} must be "medium" or "high"`);
@@ -133,6 +139,8 @@ function selectPort(protocol: ProxyProtocol, sid: string, poolIndex: number): nu
133
139
 
134
140
  export type NodemavenSynthesisInput = {
135
141
  policy: ProviderProxyPolicy;
142
+ /** Explicit credentials; synthesis never reads process-global state. */
143
+ credentials: NodemavenCredentials;
136
144
  affinityKey: string | undefined;
137
145
  protocol: ProxyProtocol;
138
146
  poolIndex: number;
@@ -159,15 +167,15 @@ export type NodemavenSynthesis = {
159
167
  * There is no allocation API — geo/session are encoded in the username.
160
168
  */
161
169
  export function synthesizeNodemavenProxy(input: NodemavenSynthesisInput): NodemavenSynthesis {
162
- const username = readNodemavenUsername();
163
- const password = readNodemavenPassword();
170
+ const username = input.credentials.username.trim();
171
+ const password = input.credentials.password.trim();
164
172
  if (!username || !password) {
165
173
  throw new Error(
166
174
  `NodeMaven credentials missing: set ${NODEMAVEN_USERNAME_ENV} and ${NODEMAVEN_PASSWORD_ENV}.`,
167
175
  );
168
176
  }
169
177
 
170
- const filter = resolveNodemavenFilter();
178
+ const filter = resolveNodemavenFilter(input.credentials.filter);
171
179
  const sid = deriveSid(input.policy, input.affinityKey, input.poolIndex, input.refreshEpoch);
172
180
  const port = selectPort(input.protocol, sid, input.poolIndex);
173
181
  const lifetimeMinutes = nodemavenLifetimeMinutes(input.policy);
@@ -40,7 +40,10 @@ import { createEnvContext } from "../runtime/env.js";
40
40
  import { executeOperation } from "../runtime/executor.js";
41
41
  import { createHttpClient } from "../runtime/http.js";
42
42
  import { wrapWithInstrumentation } from "../runtime/instrumentation.js";
43
- import { createNativeNetworkClient } from "../runtime/native-network.js";
43
+ import {
44
+ createEnvVendorCredentialResolver,
45
+ createNativeNetworkClient,
46
+ } from "../runtime/native-network.js";
44
47
  import { getProviderBaseUrl } from "../runtime/provider.js";
45
48
  import {
46
49
  PROXY_AUTH_IP_DENIED_CODE,
@@ -376,6 +379,7 @@ function createProviderContext(
376
379
  egress: provider.native.network,
377
380
  proxyPolicy: resolveNativeProxyPolicy(provider),
378
381
  affinityKey: proxyClientOptions.affinityKey,
382
+ credentials: createEnvVendorCredentialResolver(env),
379
383
  }),
380
384
  },
381
385
  }
@@ -489,6 +493,9 @@ function createAuthFlowContext(
489
493
  egress: provider.native.network,
490
494
  proxyPolicy: resolveNativeProxyPolicy(provider),
491
495
  affinityKey: proxyClientOptions.affinityKey,
496
+ credentials: createEnvVendorCredentialResolver(
497
+ createEnvContext(provider.secrets?.map((secret) => secret.name)),
498
+ ),
492
499
  }),
493
500
  },
494
501
  }
package/src/types.ts CHANGED
@@ -1318,6 +1318,11 @@ export interface NativeTcpEgressRule {
1318
1318
  /**
1319
1319
  * Bounded native TCP egress discovered through a declared bootstrap endpoint.
1320
1320
  * Host suffixes are exact DNS suffixes, not wildcard patterns.
1321
+ * Dynamic rules must declare at least one target host selector through
1322
+ * targetHostSuffixes, targetIpv4Cidrs, and/or targetIpv6Cidrs. Literal grant
1323
+ * sources and targets match only same-family selectors (except exact
1324
+ * sourceHost); DNS names match only host/suffix selectors. IPv4-mapped and
1325
+ * IPv4-compatible IPv6 literals are authorized only by IPv4 CIDRs.
1321
1326
  *
1322
1327
  * Dynamic rules are ordered. The first rule whose source, target, port, and TLS
1323
1328
  * selectors match exclusively owns the grant; its ttlMs and maxGrants bounds
@@ -1328,9 +1333,13 @@ export interface NativeTcpEgressRule {
1328
1333
  export interface NativeTcpDynamicEgressRule {
1329
1334
  readonly sourceHost?: string;
1330
1335
  readonly sourceHostSuffixes?: readonly string[];
1336
+ readonly sourceIpv4Cidrs?: readonly string[];
1337
+ readonly sourceIpv6Cidrs?: readonly string[];
1331
1338
  readonly sourcePorts?: readonly number[];
1332
1339
  readonly sourcePortRanges?: readonly NativeTcpPortRange[];
1333
- readonly targetHostSuffixes: readonly string[];
1340
+ readonly targetHostSuffixes?: readonly string[];
1341
+ readonly targetIpv4Cidrs?: readonly string[];
1342
+ readonly targetIpv6Cidrs?: readonly string[];
1334
1343
  readonly targetPorts?: readonly number[];
1335
1344
  readonly targetPortRanges?: readonly NativeTcpPortRange[];
1336
1345
  readonly tls: NativeTcpTlsMode;