@apifuse/provider-sdk 2.2.0-beta.20 → 2.2.0-beta.21

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.
@@ -37,6 +37,7 @@ export declare const ProviderServerStatefulForwardEnvelopeSchema: z.ZodObject<{
37
37
  credentials: "credentials";
38
38
  oauth2: "oauth2";
39
39
  "platform-managed": "platform-managed";
40
+ oauth2_proxied: "oauth2_proxied";
40
41
  }>;
41
42
  secrets: z.ZodRecord<z.ZodString, z.ZodString>;
42
43
  scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -142,14 +143,14 @@ export type ProviderServerOptions = {
142
143
  * @example
143
144
  * ```ts
144
145
  * await serve(provider, {
145
- * shutdown: {
146
- * hooks: [
147
- * async () => { await emitter.flush(); },
148
- * async () => { await sessionManager.closeAll("server-shutdown"); },
149
- * async () => { await lease.release(); },
150
- * async () => { await router.close(); },
151
- * ],
152
- * },
146
+ * shutdown: {
147
+ * hooks: [
148
+ * async () => { await emitter.flush(); },
149
+ * async () => { await sessionManager.closeAll("server-shutdown"); },
150
+ * async () => { await lease.release(); },
151
+ * async () => { await router.close(); },
152
+ * ],
153
+ * },
153
154
  * });
154
155
  * ```
155
156
  */
@@ -296,6 +296,7 @@ function createAuthFlowContext(provider, request, options = {}, signal) {
296
296
  : undefined;
297
297
  return {
298
298
  context: {
299
+ flowId: request.flowId,
299
300
  connectionId: request.connectionId,
300
301
  externalRef: request.externalRef,
301
302
  tenantId: request.tenantId ?? "",
@@ -318,7 +319,12 @@ function createAuthFlowContext(provider, request, options = {}, signal) {
318
319
  },
319
320
  }
320
321
  : {}),
321
- env: createEnvContext(provider.secrets?.map((secret) => secret.name)),
322
+ env: createEnvContext([
323
+ ...(provider.secrets?.map((secret) => secret.name) ?? []),
324
+ ...(provider.auth?.mode === "oauth2_proxied"
325
+ ? ["APIFUSE__AUTH_PROXY__URL"]
326
+ : []),
327
+ ]),
322
328
  credential,
323
329
  context: flowContextStore.context,
324
330
  stt: options.stt ?? createSttClientFromEnv(provider.stt),
@@ -4,6 +4,7 @@ export declare const ConnectionModeSchema: z.ZodEnum<{
4
4
  credentials: "credentials";
5
5
  oauth2: "oauth2";
6
6
  "platform-managed": "platform-managed";
7
+ oauth2_proxied: "oauth2_proxied";
7
8
  }>;
8
9
  export declare const OperationConnectionSchema: z.ZodObject<{
9
10
  id: z.ZodString;
@@ -12,6 +13,7 @@ export declare const OperationConnectionSchema: z.ZodObject<{
12
13
  credentials: "credentials";
13
14
  oauth2: "oauth2";
14
15
  "platform-managed": "platform-managed";
16
+ oauth2_proxied: "oauth2_proxied";
15
17
  }>;
16
18
  secrets: z.ZodRecord<z.ZodString, z.ZodString>;
17
19
  scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -29,6 +31,7 @@ export declare const OperationRequestSchema: z.ZodObject<{
29
31
  credentials: "credentials";
30
32
  oauth2: "oauth2";
31
33
  "platform-managed": "platform-managed";
34
+ oauth2_proxied: "oauth2_proxied";
32
35
  }>;
33
36
  secrets: z.ZodRecord<z.ZodString, z.ZodString>;
34
37
  scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -119,6 +122,7 @@ export declare const AuthFlowRequestSchema: z.ZodObject<{
119
122
  credentials: "credentials";
120
123
  oauth2: "oauth2";
121
124
  "platform-managed": "platform-managed";
125
+ oauth2_proxied: "oauth2_proxied";
122
126
  }>;
123
127
  secrets: z.ZodRecord<z.ZodString, z.ZodString>;
124
128
  scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -1,7 +1,13 @@
1
1
  import { z } from "zod";
2
2
  import { PROVIDER_ERROR_SOURCES } from "../observability.js";
3
3
  import { HttpRetryPreset } from "../types.js";
4
- export const ConnectionModeSchema = z.enum(["oauth2", "credentials", "platform-managed", "none"]);
4
+ export const ConnectionModeSchema = z.enum([
5
+ "oauth2",
6
+ "oauth2_proxied",
7
+ "credentials",
8
+ "platform-managed",
9
+ "none",
10
+ ]);
5
11
  export const OperationConnectionSchema = z.object({
6
12
  id: z.string(),
7
13
  mode: ConnectionModeSchema,
@@ -11,7 +11,13 @@ import { findStreamCaptureGroup, replayStreamEvidence } from "../stream-evidence
11
11
  // A single lowercase segment (no hyphen) is a valid id, so the trailing group
12
12
  // is optional (`*`), matching providers like `kakaomap`, `kstartup`, `triple`.
13
13
  const CONNECTOR_ID_REGEX = /^[a-z][a-z0-9]*(-[a-z][a-z0-9]*)*$/;
14
- const VALID_AUTH_MODES = ["none", "platform-managed", "credentials", "oauth2"];
14
+ const VALID_AUTH_MODES = [
15
+ "none",
16
+ "platform-managed",
17
+ "credentials",
18
+ "oauth2",
19
+ "oauth2_proxied",
20
+ ];
15
21
  const UPDATE_SNAPSHOT_ARGS = new Set(["-u", "--update-snapshots"]);
16
22
  const snapshotCaptureStates = new WeakMap();
17
23
  function isFixtureEnvelope(value) {
@@ -556,7 +562,7 @@ function formatJsonDiff(current, expected) {
556
562
  const expectedLine = expectedLines[index];
557
563
  if (currentLine === expectedLine) {
558
564
  if (currentLine !== undefined) {
559
- lines.push(` ${currentLine}`);
565
+ lines.push(` ${currentLine}`);
560
566
  }
561
567
  continue;
562
568
  }
package/dist/types.d.ts CHANGED
@@ -47,6 +47,8 @@ export interface OperationToolRouterMetadata {
47
47
  riskClass?: OperationRiskClass;
48
48
  /** OpenAI remote-MCP approval hint. Defaults from riskClass. */
49
49
  approval?: OperationApprovalPolicy;
50
+ /** Canonical operation-level connection requirement consumed by the registry and Gateway. */
51
+ connectionMode?: "none" | "optional" | "required";
50
52
  /** Override connection requirement when provider auth + openWorld inference is insufficient. */
51
53
  requiresConnection?: boolean;
52
54
  /** Public argument used to resolve the tenant-owned connection. Defaults to externalRef. */
@@ -648,7 +650,7 @@ export interface StealthProfile {
648
650
  h2Settings?: Record<string, unknown>;
649
651
  headerOrder?: string[];
650
652
  }
651
- export type AuthMode = "none" | "platform-managed" | "credentials" | "oauth2";
653
+ export type AuthMode = "none" | "platform-managed" | "credentials" | "oauth2" | "oauth2_proxied";
652
654
  export type ConnectionMode = AuthMode;
653
655
  export type ProviderReviewed = "first-party" | "community" | "staging";
654
656
  export type ProviderAccessVisibility = "public" | "early_access";
@@ -658,18 +660,18 @@ export type ProviderProxyMode = "disabled" | "optional" | "required";
658
660
  * (a common mistake because the names collide with a well-known rebrand):
659
661
  *
660
662
  * - `smartproxy` — **api.smartproxy.org**, a residential proxy with an IP
661
- * *extraction/allocation* API (app_key → a pool of raw `ip:port` CONNECT
662
- * endpoints). This is our own vendor. It is NOT the company formerly named
663
- * "Smartproxy". Credentials: `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
663
+ * *extraction/allocation* API (app_key → a pool of raw `ip:port` CONNECT
664
+ * endpoints). This is our own vendor. It is NOT the company formerly named
665
+ * "Smartproxy". Credentials: `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
664
666
  * - `nodemaven` — **gate.nodemaven.com**, a *gateway* proxy with static
665
- * credentials; geo/session encoded in the username, no allocation API.
667
+ * credentials; geo/session encoded in the username, no allocation API.
666
668
  * - `decodo` — **decodo.com**, the *gateway* proxy that was named "Smartproxy"
667
- * (smartproxy.com) before its 2025 rebrand to Decodo. Sticky sessions via
668
- * username params. A different company from `smartproxy` above.
669
- * **@deprecated** — unused; no managed adapter. Use `smartproxy`/`nodemaven`,
670
- * or the `APIFUSE__PROXY__URL` bring-your-own escape hatch.
669
+ * (smartproxy.com) before its 2025 rebrand to Decodo. Sticky sessions via
670
+ * username params. A different company from `smartproxy` above.
671
+ * **@deprecated** — unused; no managed adapter. Use `smartproxy`/`nodemaven`,
672
+ * or the `APIFUSE__PROXY__URL` bring-your-own escape hatch.
671
673
  * - `custom` — **@deprecated** bring-your-own static proxy URL marker. The
672
- * `APIFUSE__PROXY__URL` env still works without declaring this value.
674
+ * `APIFUSE__PROXY__URL` env still works without declaring this value.
673
675
  */
674
676
  export type ProviderProxyProvider = "smartproxy" | "nodemaven" | "decodo" | "custom";
675
677
  export type ProviderProxySessionAffinity = "request" | "operation" | "auth-flow" | "connection";
@@ -715,9 +717,9 @@ export interface ProviderAccessConfig {
715
717
  * Provider-level rollout visibility.
716
718
  *
717
719
  * - `public`: visible in public docs/catalog/OpenAPI and callable through
718
- * the existing provider policy stack.
720
+ * the existing provider policy stack.
719
721
  * - `early_access`: hidden from public discovery and callable only when the
720
- * active customer organization has a provider-level access grant.
722
+ * active customer organization has a provider-level access grant.
721
723
  *
722
724
  * This is intentionally provider-level only. It does not alter auth mode,
723
725
  * operation schemas, health-check authoring, `openWorld`, or Connection
@@ -1528,6 +1530,8 @@ export interface AuthFlowTerminalContext {
1528
1530
  }): AuthTurn;
1529
1531
  }
1530
1532
  export interface FlowContext {
1533
+ /** Gateway auth-flow id. Required by flow-scoped auth ceremonies. */
1534
+ flowId?: string;
1531
1535
  connectionId?: string;
1532
1536
  externalRef?: string;
1533
1537
  tenantId: string;
@@ -1633,8 +1637,20 @@ export interface ProviderContext {
1633
1637
  stt: SttContext;
1634
1638
  choice: ProviderChoiceContext;
1635
1639
  }
1640
+ export interface ProxiedOAuthConfig {
1641
+ authorizeUrl: string;
1642
+ tokenUrl: string;
1643
+ customScheme: string;
1644
+ rewriteProfile: string;
1645
+ clientIdEnvKey: string;
1646
+ pkce?: "S256" | "none";
1647
+ authorizeParams?: Record<string, string>;
1648
+ tokenParams?: Record<string, string>;
1649
+ }
1636
1650
  export interface AuthConfig {
1637
1651
  mode: AuthMode;
1652
+ /** Browser reverse-proxy contract for providers with custom-scheme OAuth callbacks. */
1653
+ proxied?: ProxiedOAuthConfig;
1638
1654
  flow?: AuthFlowDefinition;
1639
1655
  }
1640
1656
  export interface ProviderSecretDeclaration {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.2.0-beta.20",
2
+ "version": "2.2.0-beta.21",
3
3
  "name": "@apifuse/provider-sdk",
4
4
  "private": false,
5
5
  "type": "module",
@@ -26,6 +26,15 @@ const validateAuthTurn = ajv.compile(AUTH_TURN_SCHEMA);
26
26
 
27
27
  const OAUTH2_STATE_KEY = "__oauth2_state";
28
28
  const OAUTH2_PKCE_VERIFIER_KEY = "__oauth2_pkce_verifier";
29
+ export const OAUTH2_PROXIED_AUTH_PROXY_ORIGIN_ENV_KEY = "APIFUSE__AUTH_PROXY__URL";
30
+ export const OAUTH2_PROXIED_PKCE_VERIFIER_KEY = "__oauth2_proxied_pkce_verifier";
31
+ const OAUTH2_PROXIED_RESERVED_AUTHORIZE_PARAMS = new Set([
32
+ "client_id",
33
+ "response_type",
34
+ "state",
35
+ "code_challenge",
36
+ "code_challenge_method",
37
+ ]);
29
38
  const DEVICE_FLOW_KEY = "__device_flow";
30
39
  const MAGIC_LINK_KEY = "__magic_link";
31
40
  const COMBINED_STAGE_KEY = "__combined_stage";
@@ -248,6 +257,76 @@ export function createOAuth2Ceremony(options: {
248
257
  };
249
258
  }
250
259
 
260
+ /**
261
+ * Builds the start handler for a custom-scheme OAuth provider. The shared
262
+ * auth-proxy owns state minting and callback capture, while the provider owns
263
+ * token exchange and any following authentication turns.
264
+ */
265
+ export function createOAuth2ProxiedStart(
266
+ options: import("../types.js").ProxiedOAuthConfig,
267
+ ): import("../types.js").AuthFlowStartHandler {
268
+ const pkce = options.pkce ?? "S256";
269
+
270
+ return (ctx) =>
271
+ runCeremonyHandler(
272
+ async () => {
273
+ for (const key of Object.keys(options.authorizeParams ?? {})) {
274
+ if (OAUTH2_PROXIED_RESERVED_AUTHORIZE_PARAMS.has(key.toLowerCase())) {
275
+ throw new ValidationError(
276
+ `OAuth2 proxied authorizeParams cannot override reserved parameter "${key}".`,
277
+ );
278
+ }
279
+ }
280
+ const proxyOrigin = ctx.env.get(OAUTH2_PROXIED_AUTH_PROXY_ORIGIN_ENV_KEY);
281
+ if (!proxyOrigin) {
282
+ throw new ProviderSecretError(
283
+ `Missing required platform environment: ${OAUTH2_PROXIED_AUTH_PROXY_ORIGIN_ENV_KEY}`,
284
+ );
285
+ }
286
+ const clientId = getRequiredEnv(ctx, options.clientIdEnvKey);
287
+ if (!ctx.flowId) {
288
+ throw new ValidationError(
289
+ "OAuth2 proxied start requires the gateway flow id.",
290
+ );
291
+ }
292
+
293
+ const authorizePath = new URL(options.authorizeUrl).pathname;
294
+ const url = new URL(
295
+ `/p/${encodeURIComponent(ctx.providerId)}/f/${encodeURIComponent(ctx.flowId)}${authorizePath}`,
296
+ proxyOrigin,
297
+ );
298
+ url.searchParams.set("client_id", clientId);
299
+ url.searchParams.set("response_type", "code");
300
+
301
+ if (pkce === "S256") {
302
+ const verifier = createCodeVerifier();
303
+ ctx.context.set(OAUTH2_PROXIED_PKCE_VERIFIER_KEY, verifier);
304
+ url.searchParams.set("code_challenge", createCodeChallenge(verifier));
305
+ url.searchParams.set("code_challenge_method", "S256");
306
+ }
307
+
308
+ for (const [key, value] of Object.entries(options.authorizeParams ?? {})) {
309
+ url.searchParams.set(key, value);
310
+ }
311
+
312
+ return createTurn("redirect", {
313
+ data: { url: url.toString() },
314
+ hint: "Open the provider authorization page to continue.",
315
+ expectedInput: {
316
+ type: "object",
317
+ required: ["code", "state"],
318
+ properties: {
319
+ code: { type: "string" },
320
+ state: { type: "string" },
321
+ },
322
+ },
323
+ });
324
+ },
325
+ "OAuth2 proxied start failed",
326
+ ctx,
327
+ );
328
+ }
329
+
251
330
  export function createDeviceFlowCeremony(options: {
252
331
  deviceCodeUrl: string;
253
332
  tokenUrl: string;
package/src/define.ts CHANGED
@@ -84,7 +84,36 @@ interface ProviderImplementationProfile {
84
84
  const CONNECTOR_ID_REGEX = /^[a-z][a-z0-9]*(-[a-z][a-z0-9]*)*$/;
85
85
  const OPERATION_ID_REGEX = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/;
86
86
  const VALID_RUNTIMES = ["standard", "shared", "browser"] as const;
87
- const VALID_AUTH_MODES = ["none", "platform-managed", "credentials", "oauth2"] as const;
87
+ const VALID_AUTH_MODES = [
88
+ "none",
89
+ "platform-managed",
90
+ "credentials",
91
+ "oauth2",
92
+ "oauth2_proxied",
93
+ ] as const;
94
+ const PROXIED_OAUTH_REQUIRED_FIELDS = [
95
+ "authorizeUrl",
96
+ "tokenUrl",
97
+ "customScheme",
98
+ "rewriteProfile",
99
+ "clientIdEnvKey",
100
+ ] as const;
101
+ const PROXIED_OAUTH_ALLOWED_FIELDS = new Set([
102
+ ...PROXIED_OAUTH_REQUIRED_FIELDS,
103
+ "pkce",
104
+ "authorizeParams",
105
+ "tokenParams",
106
+ ]);
107
+ const PROXIED_OAUTH_RESERVED_AUTHORIZE_PARAMS = new Set([
108
+ "client_id",
109
+ "response_type",
110
+ "state",
111
+ "code_challenge",
112
+ "code_challenge_method",
113
+ ]);
114
+ const PROXIED_OAUTH_PROFILE_REGEX = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
115
+ const PROXIED_OAUTH_ENV_KEY_REGEX = /^[A-Z][A-Z0-9_]*__[A-Z0-9_]+$/;
116
+ const CUSTOM_SCHEME_REGEX = /^[A-Za-z][A-Za-z0-9+.-]*:\/\/\S+$/;
88
117
  const VALID_PROVIDER_ACCESS_VISIBILITIES = ["public", "early_access"] as const;
89
118
  const VALID_PROVIDER_PROXY_MODES = ["disabled", "optional", "required"] as const;
90
119
  const VALID_PROVIDER_PROXY_PROVIDERS = ["smartproxy", "nodemaven", "decodo", "custom"] as const;
@@ -303,6 +332,111 @@ function assertLiteralField<TValue extends string>(
303
332
  );
304
333
  }
305
334
  }
335
+
336
+ function validateProxiedOAuthParams(
337
+ value: unknown,
338
+ field: "authorizeParams" | "tokenParams",
339
+ providerId: string,
340
+ ): void {
341
+ if (value === undefined) return;
342
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
343
+ throw new ValidationError(
344
+ `Provider "${providerId}" auth.proxied.${field} must be an object of string values.`,
345
+ );
346
+ }
347
+ for (const [key, paramValue] of Object.entries(value)) {
348
+ if (!key.trim() || typeof paramValue !== "string") {
349
+ throw new ValidationError(
350
+ `Provider "${providerId}" auth.proxied.${field} must contain non-empty keys and string values.`,
351
+ );
352
+ }
353
+ if (
354
+ field === "authorizeParams" &&
355
+ PROXIED_OAUTH_RESERVED_AUTHORIZE_PARAMS.has(key.toLowerCase())
356
+ ) {
357
+ throw new ValidationError(
358
+ `Provider "${providerId}" auth.proxied.authorizeParams cannot override reserved parameter "${key}".`,
359
+ );
360
+ }
361
+ }
362
+ }
363
+
364
+ function validateProxiedOAuthAuth(auth: Record<string, unknown>, providerId: string): void {
365
+ const proxied = auth.proxied;
366
+ if (auth.mode !== "oauth2_proxied") {
367
+ if (proxied !== undefined) {
368
+ throw new ValidationError(
369
+ `Provider "${providerId}" auth.proxied is only valid when auth.mode is "oauth2_proxied".`,
370
+ );
371
+ }
372
+ return;
373
+ }
374
+ if (!proxied || typeof proxied !== "object" || Array.isArray(proxied)) {
375
+ throw new ValidationError(
376
+ `Provider "${providerId}" with auth.mode "oauth2_proxied" must declare auth.proxied.`,
377
+ );
378
+ }
379
+ const config = Object.fromEntries(Object.entries(proxied));
380
+ for (const key of Object.keys(config)) {
381
+ if (!PROXIED_OAUTH_ALLOWED_FIELDS.has(key)) {
382
+ throw new ValidationError(
383
+ `Provider "${providerId}" has unknown auth.proxied field "${key}".`,
384
+ );
385
+ }
386
+ }
387
+ for (const field of PROXIED_OAUTH_REQUIRED_FIELDS) {
388
+ if (typeof config[field] !== "string" || !config[field].trim()) {
389
+ throw new ValidationError(
390
+ `Provider "${providerId}" auth.proxied.${field} must be a non-empty string.`,
391
+ );
392
+ }
393
+ }
394
+ for (const field of ["authorizeUrl", "tokenUrl"] as const) {
395
+ try {
396
+ const endpoint = new URL(String(config[field]));
397
+ if (
398
+ endpoint.protocol !== "https:" ||
399
+ endpoint.username ||
400
+ endpoint.password ||
401
+ endpoint.hash
402
+ ) {
403
+ throw new Error("invalid endpoint");
404
+ }
405
+ } catch {
406
+ throw new ValidationError(
407
+ `Provider "${providerId}" auth.proxied.${field} must be an absolute HTTPS URL without credentials or a fragment.`,
408
+ );
409
+ }
410
+ }
411
+ const customScheme = String(config.customScheme);
412
+ if (
413
+ !CUSTOM_SCHEME_REGEX.test(customScheme) ||
414
+ customScheme.toLowerCase().startsWith("http://") ||
415
+ customScheme.toLowerCase().startsWith("https://")
416
+ ) {
417
+ throw new ValidationError(
418
+ `Provider "${providerId}" auth.proxied.customScheme must be a non-HTTP custom-scheme URL prefix.`,
419
+ );
420
+ }
421
+ if (!PROXIED_OAUTH_PROFILE_REGEX.test(String(config.rewriteProfile))) {
422
+ throw new ValidationError(
423
+ `Provider "${providerId}" auth.proxied.rewriteProfile must be a kebab-case profile name.`,
424
+ );
425
+ }
426
+ if (!PROXIED_OAUTH_ENV_KEY_REGEX.test(String(config.clientIdEnvKey))) {
427
+ throw new ValidationError(
428
+ `Provider "${providerId}" auth.proxied.clientIdEnvKey must be an APIFuse-style uppercase environment key.`,
429
+ );
430
+ }
431
+ if (config.pkce !== undefined && config.pkce !== "S256" && config.pkce !== "none") {
432
+ throw new ValidationError(
433
+ `Provider "${providerId}" auth.proxied.pkce must be "S256" or "none".`,
434
+ );
435
+ }
436
+ validateProxiedOAuthParams(config.authorizeParams, "authorizeParams", providerId);
437
+ validateProxiedOAuthParams(config.tokenParams, "tokenParams", providerId);
438
+ }
439
+
306
440
  function validateProviderShape(config: unknown): void {
307
441
  assertObjectConfig(config);
308
442
  assertRequiredField(config, "id");
@@ -315,6 +449,9 @@ function validateProviderShape(config: unknown): void {
315
449
  const auth = config.auth;
316
450
  if (auth && typeof auth === "object" && "mode" in auth && typeof auth.mode === "string")
317
451
  assertLiteralField(auth.mode, "auth.mode", VALID_AUTH_MODES, String(config.id));
452
+ if (auth && typeof auth === "object" && !Array.isArray(auth)) {
453
+ validateProxiedOAuthAuth(Object.fromEntries(Object.entries(auth)), String(config.id));
454
+ }
318
455
  if (auth && typeof auth === "object" && "exchange" in auth) {
319
456
  throw new ProviderError(
320
457
  `Provider "${String(config.id)}" auth.exchange is not part of the Provider SDK auth contract`,
package/src/index.ts CHANGED
@@ -277,6 +277,7 @@ export type {
277
277
  ProviderProxyConfig,
278
278
  ProviderProxyMode,
279
279
  ProviderProxyPolicy,
280
+ ProxiedOAuthConfig,
280
281
  ProviderProxyProvider,
281
282
  ProviderProxySessionAffinity,
282
283
  ProviderPublicConnectionMode,
package/src/lint.ts CHANGED
@@ -3,7 +3,13 @@ import type { ZodType } from "zod";
3
3
  import { lintPublicSchemaFieldNames } from "./public-schema-field-lint.js";
4
4
  import { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_SENSITIVE_META_KEY } from "./schema.js";
5
5
 
6
- type AuthModeLike = "none" | "platform-managed" | "credentials" | "oauth2" | "api-key";
6
+ type AuthModeLike =
7
+ | "none"
8
+ | "platform-managed"
9
+ | "credentials"
10
+ | "oauth2"
11
+ | "oauth2_proxied"
12
+ | "api-key";
7
13
 
8
14
  type ProviderAuthLike = {
9
15
  mode?: AuthModeLike;
package/src/provider.ts CHANGED
@@ -148,6 +148,7 @@ export type {
148
148
  ProviderLocaleKeyInput,
149
149
  ProviderLogoProfile,
150
150
  ProviderProxyPolicy,
151
+ ProxiedOAuthConfig,
151
152
  ProviderPublicConnectionMode,
152
153
  ProviderPublicProfile,
153
154
  ProviderResolvedFile,
@@ -48,6 +48,7 @@ export function createScratchpad(
48
48
  }
49
49
 
50
50
  export function createFlowContext(options: {
51
+ flowId?: string;
51
52
  http: HttpClient;
52
53
  stealth: StealthClient;
53
54
  env: EnvContext;
@@ -60,6 +61,7 @@ export function createFlowContext(options: {
60
61
  stt?: SttContext;
61
62
  }): FlowContext {
62
63
  return {
64
+ flowId: options.flowId,
63
65
  connectionId: options.connectionId,
64
66
  externalRef: options.externalRef,
65
67
  tenantId: options.tenantId,