import { FetchHttpClient, HttpClient, HttpClientRequest,} from "@effect/platform";import { createSdkMcpConnector, discoverMcpToolsFromConnector,} from "@executor/codemode-mcp";import { extractGoogleDiscoveryManifest,} from "@executor/codemode-google-discovery";import { extractOpenApiManifest, parseOpenApiDocument,} from "@executor/codemode-openapi";import { type SourceAuthInference, type SourceDiscoveryResult, type SourceProbeAuth,} from "#schema";import * as Effect from "effect/Effect";import { getIntrospectionQuery } from "graphql";import { startMcpOAuthAuthorization } from "./mcp-oauth";import { namespaceFromSourceName } from "./source-names"; const GRAPHQL_INTROSPECTION_QUERY = getIntrospectionQuery(); type HttpProbeResponse = { status: number; headers: Readonly<Record<string, string>>; text: string;}; type OpenApiProbeResult = { result: SourceDiscoveryResult;}; type GoogleDiscoveryProbeResult = { result: SourceDiscoveryResult;}; type GraphqlProbeResult = { result: SourceDiscoveryResult;}; type McpProbeResult = { result: SourceDiscoveryResult;}; type OpenApiSecurityCandidate = { name: string; kind: "bearer" | "oauth2" | "apiKey" | "basic" | "unknown"; supported: boolean; headerName: string | null; prefix: string | null; parameterName: string | null; parameterLocation: "header" | "query" | "cookie" | null; oauthAuthorizationUrl: string | null; oauthTokenUrl: string | null; oauthScopes: string[]; reason: string;}; const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value); const asString = (value: unknown): string | null => typeof value === "string" && value.length > 0 ? value : null; const trimOrNull = (value: string | null | undefined): string | null => { if (value == null) { return null; } const trimmed = value.trim(); return trimmed.length > 0 ? trimmed : null;}; const defaultNameFromEndpoint = (endpoint: string): string => new URL(endpoint).hostname; const normalizeUrl = (value: string): string => { const trimmed = value.trim(); if (trimmed.length === 0) { throw new Error("Source URL is required"); } const parsed = new URL(trimmed); if (parsed.protocol !== "http:" && parsed.protocol !== "https:") { throw new Error("Source URL must use http or https"); } return parsed.toString();}; const unsupportedAuthInference = ( kind: SourceAuthInference["suggestedKind"], input: Omit<SourceAuthInference, "suggestedKind" | "supported">,): SourceAuthInference => ({ ...input, suggestedKind: kind, supported: false,}); const supportedAuthInference = ( kind: Extract<SourceAuthInference["suggestedKind"], "none" | "bearer" | "oauth2">, input: Omit<SourceAuthInference, "suggestedKind" | "supported">,): SourceAuthInference => ({ ...input, suggestedKind: kind, supported: true,}); const unknownAuthInference = (reason: string): SourceAuthInference => ({ suggestedKind: "unknown", confidence: "low", supported: false, reason, headerName: null, prefix: null, parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: [],}); const noneAuthInference = ( reason: string, confidence: SourceAuthInference["confidence"] = "high",): SourceAuthInference => supportedAuthInference("none", { confidence, reason, headerName: null, prefix: null, parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: [],}); const parseChallengeAuthInference = ( headers: Readonly<Record<string, string>>, fallbackReason: string,): SourceAuthInference => { const challenge = headers["www-authenticate"] ?? headers["WWW-Authenticate"]; if (!challenge) { return unknownAuthInference(fallbackReason); } const normalized = challenge.toLowerCase(); if (normalized.includes("bearer")) { return supportedAuthInference("bearer", { confidence: normalized.includes("realm=") ? "medium" : "low", reason: `Derived from HTTP challenge: ${challenge}`, headerName: "Authorization", prefix: "Bearer ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: [], }); } if (normalized.includes("basic")) { return unsupportedAuthInference("basic", { confidence: "medium", reason: `Derived from HTTP challenge: ${challenge}`, headerName: "Authorization", prefix: "Basic ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: [], }); } return unknownAuthInference(fallbackReason);}; const probeHeadersFromAuth = (probeAuth: SourceProbeAuth | null | undefined): Record<string, string> => { if (probeAuth == null || probeAuth.kind === "none") { return {}; } if (probeAuth.kind === "headers") { return { ...probeAuth.headers }; } if (probeAuth.kind === "basic") { return { Authorization: `Basic ${Buffer.from(`${probeAuth.username}:${probeAuth.password}`).toString("base64")}`, }; } return { [trimOrNull(probeAuth.headerName) ?? "Authorization"]: `${probeAuth.prefix ?? "Bearer "}${probeAuth.token}`, };}; const executeHttpProbe = (input: { method: "GET" | "POST"; url: string; headers?: Readonly<Record<string, string>>; body?: string;}): Effect.Effect<HttpProbeResponse, Error, never> => Effect.gen(function* () { const client = yield* HttpClient.HttpClient; let request = HttpClientRequest.make(input.method)(input.url, { headers: input.headers ?? {}, }); if (input.body !== undefined) { request = HttpClientRequest.bodyText( request, input.body, input.headers?.["content-type"] ?? input.headers?.["Content-Type"] ?? "application/json", ); } const response = yield* client.execute(request).pipe( Effect.mapError((cause) => cause instanceof Error ? cause : new Error(String(cause))), ); const text = yield* response.text.pipe( Effect.mapError((cause) => cause instanceof Error ? cause : new Error(String(cause))), ); return { status: response.status, headers: response.headers, text, } satisfies HttpProbeResponse; }).pipe(Effect.provide(FetchHttpClient.layer)); const parseStructuredDocument = (value: string): unknown => parseOpenApiDocument(value) as unknown; const readLocalRef = (document: Record<string, unknown>, ref: string): unknown => { if (!ref.startsWith("#/")) { return undefined; } let current: unknown = document; for (const rawSegment of ref.slice(2).split("/")) { const segment = rawSegment.replaceAll("~1", "/").replaceAll("~0", "~"); if (!isRecord(current)) { return undefined; } current = current[segment]; } return current;}; const resolveSecurityScheme = ( document: Record<string, unknown>, input: unknown, depth = 0,): Record<string, unknown> | null => { if (!isRecord(input)) { return null; } const ref = asString(input["$ref"]); if (ref && depth < 5) { return resolveSecurityScheme(document, readLocalRef(document, ref), depth + 1); } return input;}; const collectAppliedSecurityCandidates = (document: Record<string, unknown>): Array<{ name: string; scopes: string[];}> => { const seen = new Set<string>(); const candidates: Array<{ name: string; scopes: string[] }> = []; const addRequirementArray = (value: unknown) => { if (!Array.isArray(value)) { return; } for (const requirement of value) { if (!isRecord(requirement)) { continue; } for (const [name, scopesValue] of Object.entries(requirement)) { if (name.length === 0 || seen.has(name)) { continue; } seen.add(name); candidates.push({ name, scopes: Array.isArray(scopesValue) ? scopesValue.filter((scope): scope is string => typeof scope === "string") : [], }); } } }; addRequirementArray(document.security); const paths = document.paths; if (!isRecord(paths)) { return candidates; } for (const pathItem of Object.values(paths)) { if (!isRecord(pathItem)) { continue; } addRequirementArray(pathItem.security); for (const operation of Object.values(pathItem)) { if (!isRecord(operation)) { continue; } addRequirementArray(operation.security); } } return candidates;}; const securityCandidateFromScheme = (input: { name: string; scopes: string[]; scheme: Record<string, unknown>;}): OpenApiSecurityCandidate => { const type = asString(input.scheme.type)?.toLowerCase() ?? ""; if (type === "oauth2") { const flows = isRecord(input.scheme.flows) ? input.scheme.flows : {}; const flow = Object.values(flows).find(isRecord) ?? null; const declaredScopes = flow && isRecord(flow.scopes) ? Object.keys(flow.scopes).filter((scope) => scope.length > 0) : []; const oauthScopes = [...new Set([...input.scopes, ...declaredScopes])].sort(); return { name: input.name, kind: "oauth2", supported: true, headerName: "Authorization", prefix: "Bearer ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: flow ? trimOrNull(asString(flow.authorizationUrl)) : null, oauthTokenUrl: flow ? trimOrNull(asString(flow.tokenUrl)) : null, oauthScopes, reason: `OpenAPI security scheme \"${input.name}\" declares OAuth2`, }; } if (type === "http") { const scheme = asString(input.scheme.scheme)?.toLowerCase() ?? ""; if (scheme === "bearer") { return { name: input.name, kind: "bearer", supported: true, headerName: "Authorization", prefix: "Bearer ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: input.scopes, reason: `OpenAPI security scheme \"${input.name}\" declares HTTP bearer auth`, }; } if (scheme === "basic") { return { name: input.name, kind: "basic", supported: false, headerName: "Authorization", prefix: "Basic ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: input.scopes, reason: `OpenAPI security scheme \"${input.name}\" declares HTTP basic auth`, }; } } if (type === "apiKey") { const location = asString(input.scheme.in); const parameterLocation = location === "header" || location === "query" || location === "cookie" ? location : null; return { name: input.name, kind: "apiKey", supported: false, headerName: parameterLocation === "header" ? trimOrNull(asString(input.scheme.name)) : null, prefix: null, parameterName: trimOrNull(asString(input.scheme.name)), parameterLocation, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: input.scopes, reason: `OpenAPI security scheme \"${input.name}\" declares API key auth`, }; } return { name: input.name, kind: "unknown", supported: false, headerName: null, prefix: null, parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: input.scopes, reason: `OpenAPI security scheme \"${input.name}\" uses unsupported type ${type || "unknown"}`, };}; const inferOpenApiAuth = (document: Record<string, unknown>): SourceAuthInference => { const components = isRecord(document.components) ? document.components : {}; const securitySchemes = isRecord(components.securitySchemes) ? components.securitySchemes : {}; const appliedCandidates = collectAppliedSecurityCandidates(document); if (appliedCandidates.length === 0) { if (Object.keys(securitySchemes).length === 0) { return noneAuthInference("OpenAPI document does not declare security requirements"); } const fallbackCandidate = Object.entries(securitySchemes) .map(([name, value]) => securityCandidateFromScheme({ name, scopes: [], scheme: resolveSecurityScheme(document, value) ?? {}, })) .sort((left, right) => { const priority = { oauth2: 0, bearer: 1, apiKey: 2, basic: 3, unknown: 4 } as const; return priority[left.kind] - priority[right.kind] || left.name.localeCompare(right.name); })[0]; if (!fallbackCandidate) { return noneAuthInference("OpenAPI document does not declare security requirements"); } const confidence = fallbackCandidate.kind === "unknown" ? "low" : "medium"; if (fallbackCandidate.kind === "oauth2") { return supportedAuthInference("oauth2", { confidence, reason: `${fallbackCandidate.reason}; scheme is defined but not explicitly applied to operations`, headerName: fallbackCandidate.headerName, prefix: fallbackCandidate.prefix, parameterName: fallbackCandidate.parameterName, parameterLocation: fallbackCandidate.parameterLocation, oauthAuthorizationUrl: fallbackCandidate.oauthAuthorizationUrl, oauthTokenUrl: fallbackCandidate.oauthTokenUrl, oauthScopes: fallbackCandidate.oauthScopes, }); } if (fallbackCandidate.kind === "bearer") { return supportedAuthInference("bearer", { confidence, reason: `${fallbackCandidate.reason}; scheme is defined but not explicitly applied to operations`, headerName: fallbackCandidate.headerName, prefix: fallbackCandidate.prefix, parameterName: fallbackCandidate.parameterName, parameterLocation: fallbackCandidate.parameterLocation, oauthAuthorizationUrl: fallbackCandidate.oauthAuthorizationUrl, oauthTokenUrl: fallbackCandidate.oauthTokenUrl, oauthScopes: fallbackCandidate.oauthScopes, }); } if (fallbackCandidate.kind === "apiKey") { return unsupportedAuthInference("apiKey", { confidence, reason: `${fallbackCandidate.reason}; scheme is defined but not explicitly applied to operations`, headerName: fallbackCandidate.headerName, prefix: fallbackCandidate.prefix, parameterName: fallbackCandidate.parameterName, parameterLocation: fallbackCandidate.parameterLocation, oauthAuthorizationUrl: fallbackCandidate.oauthAuthorizationUrl, oauthTokenUrl: fallbackCandidate.oauthTokenUrl,Lines 1–500 of 989. Load more
import { FetchHttpClient, HttpClient, HttpClientRequest, } from "@effect/platform"; import { createSdkMcpConnector, discoverMcpToolsFromConnector, } from "@executor/codemode-mcp"; import { extractGoogleDiscoveryManifest, } from "@executor/codemode-google-discovery"; import { extractOpenApiManifest, parseOpenApiDocument, } from "@executor/codemode-openapi"; import { type SourceAuthInference, type SourceDiscoveryResult, type SourceProbeAuth, } from "#schema"; import * as Effect from "effect/Effect"; import { getIntrospectionQuery } from "graphql"; import { startMcpOAuthAuthorization } from "./mcp-oauth"; import { namespaceFromSourceName } from "./source-names"; const GRAPHQL_INTROSPECTION_QUERY = getIntrospectionQuery(); type HttpProbeResponse = { status: number; headers: Readonly<Record<string, string>>; text: string; }; type OpenApiProbeResult = { result: SourceDiscoveryResult; }; type GoogleDiscoveryProbeResult = { result: SourceDiscoveryResult; }; type GraphqlProbeResult = { result: SourceDiscoveryResult; }; type McpProbeResult = { result: SourceDiscoveryResult; }; type OpenApiSecurityCandidate = { name: string; kind: "bearer" | "oauth2" | "apiKey" | "basic" | "unknown"; supported: boolean; headerName: string | null; prefix: string | null; parameterName: string | null; parameterLocation: "header" | "query" | "cookie" | null; oauthAuthorizationUrl: string | null; oauthTokenUrl: string | null; oauthScopes: string[]; reason: string; }; const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value); const asString = (value: unknown): string | null => typeof value === "string" && value.length > 0 ? value : null; const trimOrNull = (value: string | null | undefined): string | null => { if (value == null) { return null; } const trimmed = value.trim(); return trimmed.length > 0 ? trimmed : null; }; const defaultNameFromEndpoint = (endpoint: string): string => new URL(endpoint).hostname; const normalizeUrl = (value: string): string => { const trimmed = value.trim(); if (trimmed.length === 0) { throw new Error("Source URL is required"); } const parsed = new URL(trimmed); if (parsed.protocol !== "http:" && parsed.protocol !== "https:") { throw new Error("Source URL must use http or https"); } return parsed.toString(); }; const unsupportedAuthInference = ( kind: SourceAuthInference["suggestedKind"], input: Omit<SourceAuthInference, "suggestedKind" | "supported">, ): SourceAuthInference => ({ ...input, suggestedKind: kind, supported: false, }); const supportedAuthInference = ( kind: Extract<SourceAuthInference["suggestedKind"], "none" | "bearer" | "oauth2">, input: Omit<SourceAuthInference, "suggestedKind" | "supported">, ): SourceAuthInference => ({ ...input, suggestedKind: kind, supported: true, }); const unknownAuthInference = (reason: string): SourceAuthInference => ({ suggestedKind: "unknown", confidence: "low", supported: false, reason, headerName: null, prefix: null, parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: [], }); const noneAuthInference = ( reason: string, confidence: SourceAuthInference["confidence"] = "high", ): SourceAuthInference => supportedAuthInference("none", { confidence, reason, headerName: null, prefix: null, parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: [], }); const parseChallengeAuthInference = ( headers: Readonly<Record<string, string>>, fallbackReason: string, ): SourceAuthInference => { const challenge = headers["www-authenticate"] ?? headers["WWW-Authenticate"]; if (!challenge) { return unknownAuthInference(fallbackReason); } const normalized = challenge.toLowerCase(); if (normalized.includes("bearer")) { return supportedAuthInference("bearer", { confidence: normalized.includes("realm=") ? "medium" : "low", reason: `Derived from HTTP challenge: ${challenge}`, headerName: "Authorization", prefix: "Bearer ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: [], }); } if (normalized.includes("basic")) { return unsupportedAuthInference("basic", { confidence: "medium", reason: `Derived from HTTP challenge: ${challenge}`, headerName: "Authorization", prefix: "Basic ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: [], }); } return unknownAuthInference(fallbackReason); }; const probeHeadersFromAuth = (probeAuth: SourceProbeAuth | null | undefined): Record<string, string> => { if (probeAuth == null || probeAuth.kind === "none") { return {}; } if (probeAuth.kind === "headers") { return { ...probeAuth.headers }; } if (probeAuth.kind === "basic") { return { Authorization: `Basic ${Buffer.from(`${probeAuth.username}:${probeAuth.password}`).toString("base64")}`, }; } return { [trimOrNull(probeAuth.headerName) ?? "Authorization"]: `${probeAuth.prefix ?? "Bearer "}${probeAuth.token}`, }; }; const executeHttpProbe = (input: { method: "GET" | "POST"; url: string; headers?: Readonly<Record<string, string>>; body?: string; }): Effect.Effect<HttpProbeResponse, Error, never> => Effect.gen(function* () { const client = yield* HttpClient.HttpClient; let request = HttpClientRequest.make(input.method)(input.url, { headers: input.headers ?? {}, }); if (input.body !== undefined) { request = HttpClientRequest.bodyText( request, input.body, input.headers?.["content-type"] ?? input.headers?.["Content-Type"] ?? "application/json", ); } const response = yield* client.execute(request).pipe( Effect.mapError((cause) => cause instanceof Error ? cause : new Error(String(cause))), ); const text = yield* response.text.pipe( Effect.mapError((cause) => cause instanceof Error ? cause : new Error(String(cause))), ); return { status: response.status, headers: response.headers, text, } satisfies HttpProbeResponse; }).pipe(Effect.provide(FetchHttpClient.layer)); const parseStructuredDocument = (value: string): unknown => parseOpenApiDocument(value) as unknown; const readLocalRef = (document: Record<string, unknown>, ref: string): unknown => { if (!ref.startsWith("#/")) { return undefined; } let current: unknown = document; for (const rawSegment of ref.slice(2).split("/")) { const segment = rawSegment.replaceAll("~1", "/").replaceAll("~0", "~"); if (!isRecord(current)) { return undefined; } current = current[segment]; } return current; }; const resolveSecurityScheme = ( document: Record<string, unknown>, input: unknown, depth = 0, ): Record<string, unknown> | null => { if (!isRecord(input)) { return null; } const ref = asString(input["$ref"]); if (ref && depth < 5) { return resolveSecurityScheme(document, readLocalRef(document, ref), depth + 1); } return input; }; const collectAppliedSecurityCandidates = (document: Record<string, unknown>): Array<{ name: string; scopes: string[]; }> => { const seen = new Set<string>(); const candidates: Array<{ name: string; scopes: string[] }> = []; const addRequirementArray = (value: unknown) => { if (!Array.isArray(value)) { return; } for (const requirement of value) { if (!isRecord(requirement)) { continue; } for (const [name, scopesValue] of Object.entries(requirement)) { if (name.length === 0 || seen.has(name)) { continue; } seen.add(name); candidates.push({ name, scopes: Array.isArray(scopesValue) ? scopesValue.filter((scope): scope is string => typeof scope === "string") : [], }); } } }; addRequirementArray(document.security); const paths = document.paths; if (!isRecord(paths)) { return candidates; } for (const pathItem of Object.values(paths)) { if (!isRecord(pathItem)) { continue; } addRequirementArray(pathItem.security); for (const operation of Object.values(pathItem)) { if (!isRecord(operation)) { continue; } addRequirementArray(operation.security); } } return candidates; }; const securityCandidateFromScheme = (input: { name: string; scopes: string[]; scheme: Record<string, unknown>; }): OpenApiSecurityCandidate => { const type = asString(input.scheme.type)?.toLowerCase() ?? ""; if (type === "oauth2") { const flows = isRecord(input.scheme.flows) ? input.scheme.flows : {}; const flow = Object.values(flows).find(isRecord) ?? null; const declaredScopes = flow && isRecord(flow.scopes) ? Object.keys(flow.scopes).filter((scope) => scope.length > 0) : []; const oauthScopes = [...new Set([...input.scopes, ...declaredScopes])].sort(); return { name: input.name, kind: "oauth2", supported: true, headerName: "Authorization", prefix: "Bearer ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: flow ? trimOrNull(asString(flow.authorizationUrl)) : null, oauthTokenUrl: flow ? trimOrNull(asString(flow.tokenUrl)) : null, oauthScopes, reason: `OpenAPI security scheme \"${input.name}\" declares OAuth2`, }; } if (type === "http") { const scheme = asString(input.scheme.scheme)?.toLowerCase() ?? ""; if (scheme === "bearer") { return { name: input.name, kind: "bearer", supported: true, headerName: "Authorization", prefix: "Bearer ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: input.scopes, reason: `OpenAPI security scheme \"${input.name}\" declares HTTP bearer auth`, }; } if (scheme === "basic") { return { name: input.name, kind: "basic", supported: false, headerName: "Authorization", prefix: "Basic ", parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: input.scopes, reason: `OpenAPI security scheme \"${input.name}\" declares HTTP basic auth`, }; } } if (type === "apiKey") { const location = asString(input.scheme.in); const parameterLocation = location === "header" || location === "query" || location === "cookie" ? location : null; return { name: input.name, kind: "apiKey", supported: false, headerName: parameterLocation === "header" ? trimOrNull(asString(input.scheme.name)) : null, prefix: null, parameterName: trimOrNull(asString(input.scheme.name)), parameterLocation, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: input.scopes, reason: `OpenAPI security scheme \"${input.name}\" declares API key auth`, }; } return { name: input.name, kind: "unknown", supported: false, headerName: null, prefix: null, parameterName: null, parameterLocation: null, oauthAuthorizationUrl: null, oauthTokenUrl: null, oauthScopes: input.scopes, reason: `OpenAPI security scheme \"${input.name}\" uses unsupported type ${type || "unknown"}`, }; }; const inferOpenApiAuth = (document: Record<string, unknown>): SourceAuthInference => { const components = isRecord(document.components) ? document.components : {}; const securitySchemes = isRecord(components.securitySchemes) ? components.securitySchemes : {}; const appliedCandidates = collectAppliedSecurityCandidates(document); if (appliedCandidates.length === 0) { if (Object.keys(securitySchemes).length === 0) { return noneAuthInference("OpenAPI document does not declare security requirements"); } const fallbackCandidate = Object.entries(securitySchemes) .map(([name, value]) => securityCandidateFromScheme({ name, scopes: [], scheme: resolveSecurityScheme(document, value) ?? {}, })) .sort((left, right) => { const priority = { oauth2: 0, bearer: 1, apiKey: 2, basic: 3, unknown: 4 } as const; return priority[left.kind] - priority[right.kind] || left.name.localeCompare(right.name); })[0]; if (!fallbackCandidate) { return noneAuthInference("OpenAPI document does not declare security requirements"); } const confidence = fallbackCandidate.kind === "unknown" ? "low" : "medium"; if (fallbackCandidate.kind === "oauth2") { return supportedAuthInference("oauth2", { confidence, reason: `${fallbackCandidate.reason}; scheme is defined but not explicitly applied to operations`, headerName: fallbackCandidate.headerName, prefix: fallbackCandidate.prefix, parameterName: fallbackCandidate.parameterName, parameterLocation: fallbackCandidate.parameterLocation, oauthAuthorizationUrl: fallbackCandidate.oauthAuthorizationUrl, oauthTokenUrl: fallbackCandidate.oauthTokenUrl, oauthScopes: fallbackCandidate.oauthScopes, }); } if (fallbackCandidate.kind === "bearer") { return supportedAuthInference("bearer", { confidence, reason: `${fallbackCandidate.reason}; scheme is defined but not explicitly applied to operations`, headerName: fallbackCandidate.headerName, prefix: fallbackCandidate.prefix, parameterName: fallbackCandidate.parameterName, parameterLocation: fallbackCandidate.parameterLocation, oauthAuthorizationUrl: fallbackCandidate.oauthAuthorizationUrl, oauthTokenUrl: fallbackCandidate.oauthTokenUrl, oauthScopes: fallbackCandidate.oauthScopes, }); } if (fallbackCandidate.kind === "apiKey") { return unsupportedAuthInference("apiKey", { confidence, reason: `${fallbackCandidate.reason}; scheme is defined but not explicitly applied to operations`, headerName: fallbackCandidate.headerName, prefix: fallbackCandidate.prefix, parameterName: fallbackCandidate.parameterName, parameterLocation: fallbackCandidate.parameterLocation, oauthAuthorizationUrl: fallbackCandidate.oauthAuthorizationUrl, oauthTokenUrl: fallbackCandidate.oauthTokenUrl,