import { z } from "zod"; import { RestApiValidationError } from "../../errors.js"; import type { TraceMetadata } from "../registry.js"; import { RestApiClientBase } from "./rest-api-client-base.js"; import type { ApiRequestOptions, ApiRequestSchema, RestApiResponseType, SupportsApiRequest, } from "./types.js"; export abstract class RestApiIntegrationClient extends RestApiClientBase implements SupportsApiRequest { async apiRequest( options: ApiRequestOptions & { responseType?: Exclude; }, schema: ApiRequestSchema & { response: z.ZodSchema; }, metadata?: TraceMetadata, ): Promise; async apiRequest( options: ApiRequestOptions & { responseType: "binary"; }, schema?: ApiRequestSchema, metadata?: TraceMetadata, ): Promise; async apiRequest( options: ApiRequestOptions & { responseType: "text"; }, schema?: ApiRequestSchema, metadata?: TraceMetadata, ): Promise; async apiRequest( options: ApiRequestOptions, schema?: ApiRequestSchema, metadata?: TraceMetadata, ): Promise { if ((options.responseType ?? "json") === "json" && !schema?.response) { throw new RestApiValidationError( 'apiRequest() with responseType "json" requires a response schema. Provide one, or set responseType to "text" or "binary"', { zodError: new z.ZodError([ { code: z.ZodIssueCode.custom, message: "response schema is required for JSON responses", path: ["response"], }, ]), data: undefined, }, ); } const result = await this.executeApiRequest( options, schema?.body, metadata, ); if (!schema?.response) { return result; } const responseParseResult = schema.response.safeParse(result); if (!responseParseResult.success) { throw new RestApiValidationError( `Response validation failed: ${responseParseResult.error.message}`, { data: result, zodError: responseParseResult.error, }, ); } return responseParseResult.data; } }