@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.
- package/AUTHORING.md +40 -0
- package/CHANGELOG.md +9 -0
- package/dist/config/loader.d.ts +19 -0
- package/dist/config/loader.js +59 -28
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/native-address.d.ts +43 -0
- package/dist/native-address.js +281 -0
- package/dist/native-egress-policy.d.ts +4 -0
- package/dist/native-egress-policy.js +86 -23
- package/dist/provider.d.ts +1 -1
- package/dist/provider.js +1 -1
- package/dist/runtime/native-network.d.ts +46 -7
- package/dist/runtime/native-network.js +590 -114
- package/dist/runtime/proxy-nodemaven.d.ts +7 -0
- package/dist/runtime/proxy-nodemaven.js +5 -5
- package/dist/server/serve.js +3 -1
- package/dist/types.d.ts +10 -1
- package/package.json +1 -1
- package/src/config/loader.ts +110 -18
- package/src/index.ts +5 -0
- package/src/native-address.ts +340 -0
- package/src/native-egress-policy.ts +105 -32
- package/src/provider.ts +5 -0
- package/src/runtime/native-network.ts +770 -136
- package/src/runtime/proxy-nodemaven.ts +13 -5
- package/src/server/serve.ts +8 -1
- package/src/types.ts +10 -1
|
@@ -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 =
|
|
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 =
|
|
163
|
-
const password =
|
|
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);
|
package/src/server/serve.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
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;
|