import { CollectionMethod } from '../utils/collector.js'; interface BaseServiceConfig { apiKey: string; silent: boolean; debug?: boolean; dryRun?: boolean; baseUrl?: string; } /** * Thrown by {@link BaseService.fetchWithHeaders} on a non-2xx response. Carries the HTTP `status` * so callers (e.g. the CLI) can react to it — a 401 vs. a 404 — without parsing the message string. */ declare class HttpError extends Error { readonly status: number; constructor(message: string, status: number); } declare abstract class BaseService { protected apiKey: string; protected silent: boolean; protected debug: boolean; protected dryRun: boolean; protected apiEndpoint: string; constructor(config: BaseServiceConfig, endpointPath: string); protected createRequestOptions(payload: any): RequestInit; protected addCollectorToData>(data: T, collectionMethod?: CollectionMethod): T & { collector: string; }; protected sendRequest(payload: any, successMessage: string): Promise; /** * Shared success/failure handling for a `fetch` response, used by both {@link sendRequest} and * {@link sendMultipart}: JSON-parse and log on 2xx, log and resolve to `null` otherwise. */ private parseJsonResponse; /** * POST a `FormData` body (multipart/form-data) — the upload counterpart to {@link sendRequest}. * Omits `Content-Type` so `fetch` sets the multipart boundary itself. There is no * `sendWithHTTPS`-style fallback for multipart, so this throws when global `fetch` is * unavailable rather than silently returning `null`, which would otherwise be indistinguishable * from a normal API failure. Non-2xx responses and network errors follow {@link sendRequest}'s * convention instead: logged and resolved to `null`. * * @throws Error if global `fetch` is unavailable (requires Node.js 18+). */ protected sendMultipart(formData: FormData, successMessage: string): Promise; private sendWithHTTPS; /** * Fetch `url` and return the raw response body text plus headers, throwing on failure. The * shared fetch/error/status-throwing primitive both {@link fetchOrThrow} (discards the headers) * and {@link getJsonWithHeaders} (JSON-parses the body, keeps the headers — e.g. for * `LoggingService#searchLogs` reading pagination totals off X-Total-Count/etc.) sit on top of. * * @param errorPrefix Prefixes thrown error messages, e.g. `"MCP request failed"` or * `"Feedback request failed"`, so each caller keeps its own established message wording. * @throws Error if global `fetch` is unavailable (Node.js < 18) or on a network failure. * {@link HttpError} (with `.status`) on a non-2xx response. */ protected fetchWithHeaders(url: string, init: RequestInit, errorPrefix: string): Promise<{ text: string; headers: Headers; }>; /** * Fetch `url` and return the raw response body text, throwing on failure. A thin wrapper around * {@link fetchWithHeaders} for callers that don't need response headers — currently just * `McpService.mcpCall` (as opposed to {@link sendRequest}'s POST/null-on-error convention). * * @param errorPrefix Prefixes thrown error messages, e.g. `"MCP request failed"`, so each * caller keeps its own established message wording. * @throws Error if global `fetch` is unavailable (Node.js < 18) or on a network failure. * {@link HttpError} (with `.status`) on a non-2xx response. */ protected fetchOrThrow(url: string, init: RequestInit, errorPrefix: string): Promise; /** * GET `url` and JSON-parse the response body, throwing on failure — the shared read-path used * by `FeedbackService`/`LoggingService`'s search/get methods (as opposed to {@link sendRequest}'s * POST/null-on-error convention). * * @param noun Capitalized noun identifying the caller, e.g. `"Feedback"` or `"Log"` — produces * `" request failed (): ..."` and `" response was not valid JSON: ..."` * so each caller keeps its own established message wording. * @throws Error on network failure or a non-JSON body. {@link HttpError} (with `.status`) on a * non-2xx response. */ protected getJson(url: string, noun: string): Promise; /** * Like {@link getJson}, but also returns the response headers — for endpoints (e.g. * searchLogs) that expose metadata like pagination totals via X-Total-Count/etc. headers * rather than the response body. * * @throws Error on network failure or a non-JSON body. {@link HttpError} (with `.status`) on a * non-2xx response. */ protected getJsonWithHeaders(url: string, noun: string): Promise<{ body: T; headers: Headers; }>; /** * Build `${this.apiEndpoint}/${id}` as a `URL` for a single-resource GET, guarding against * inputs that WHATWG `URL` parsing would resolve away rather than treat as a path segment: * blank/whitespace-only strings, and dot-segments (`.`/`..`) — `encodeURIComponent` doesn't * escape `.`, so `new URL(...)` still collapses them, silently retargeting the request to this * resource's own `index` route (or, for `..`, an unrelated path entirely) instead of 404ing. * Verifies the built URL's `pathname` still ends with the exact encoded `id` to catch both. * * @param errorMessage Thrown verbatim on a rejected `id`, e.g. * `"getFeedback: id must be a non-empty string"`, so each caller keeps its own wording. * @throws Error if `id` is blank, not a string, or resolves away via dot-segments. */ protected buildResourceUrl(id: string, errorMessage: string): URL; protected log(...args: any[]): void; protected logSeparator(): void; getApiEndpoint(): string; } export { BaseService, type BaseServiceConfig, HttpError };