import type { Layer } from "effect"; import { Effect } from "effect"; import type { HttpClient } from "effect/unstable/http"; import type { Authentication } from "./types"; import type { OpenApiIntegrationConfig } from "./config"; import type { KeepPathItem } from "./split"; import { OpenApiParseError } from "./errors"; export interface SpecFetchCredentials { readonly headers?: Record; readonly queryParams?: Record; } export interface SpecFetchInput { readonly urls: readonly string[]; readonly credentials?: SpecFetchCredentials; /** Explicit OAuth scopes selected by the caller. Format adapters may use * these to omit operations that the resulting connection cannot invoke. */ readonly consentScopes?: readonly string[]; readonly httpClientLayer: Layer.Layer; } export interface DerivedIdentity { readonly slug: string; readonly name: string; readonly description?: string; } export interface ConvertedSpec { readonly specText: string; readonly specUrl?: string; readonly baseUrl?: string; readonly authenticationTemplate?: readonly Authentication[]; readonly config?: Partial & Readonly>; readonly keepPathItem?: KeepPathItem; readonly document?: unknown; } export interface SpecFormatAdapter { readonly id: string; readonly fetch: (input: SpecFetchInput) => Effect.Effect; readonly deriveIdentity?: (doc: unknown) => DerivedIdentity | null; /** Recognizes URLs this adapter can convert. Lets a hand-pasted URL take * the same path a preset would: without this, a Google Discovery URL only * worked through a preset carrying `specFormat`, and pasting the identical * URL failed as "not OpenAPI". */ readonly detectsUrl?: (url: string) => boolean; } export const resolveSpecFormatAdapter = ( adapters: readonly SpecFormatAdapter[], id: string | undefined, url?: string, ): Effect.Effect => { if (!id) { if (!url) return Effect.succeed(null); return Effect.succeed( adapters.find((candidate) => candidate.detectsUrl?.(url) === true) ?? null, ); } const adapter = adapters.find((candidate) => candidate.id === id); if (adapter) return Effect.succeed(adapter); return Effect.fail(new OpenApiParseError({ message: `Unknown OpenAPI spec format: ${id}` })); };