import { Event } from '../../../util/vs/base/common/event';
export declare const IFetcherService: import("../../../util/common/services").ServiceIdentifier<IFetcherService>;
/** Use as the callSite value to suppress fetch telemetry for a request (e.g. from the telemetry service itself). */
export declare const NO_FETCH_TELEMETRY = "NO_FETCH_TELEMETRY";
export interface IFetcherService {
    readonly _serviceBrand: undefined;
    readonly onDidFetch: Event<FetchEvent>;
    readonly onDidCompleteFetch: Event<FetchTelemetryEvent>;
    getUserAgentLibrary(): string;
    fetch(url: string, options: FetchOptions): Promise<Response>;
    createWebSocket(url: string, options?: WebSocketConnectOptions): WebSocketConnection;
    disconnectAll(): Promise<unknown>;
    makeAbortController(): IAbortController;
    isAbortError(e: any): boolean;
    isInternetDisconnectedError(e: any): boolean;
    isFetcherError(e: any): boolean;
    isNetworkProcessCrashedError(e: any): boolean;
    getUserMessageForFetcherError(err: any): string;
    fetchWithPagination<T>(baseUrl: string, options: PaginationOptions<T>): Promise<T[]>;
}
export type FetchEvent = {
    internalId: string;
    timestamp: number;
    outcome: 'success';
    phase: 'requestResponse';
    fetcher: FetcherId;
    hostname: string;
    statusCode: number;
} | {
    internalId: string;
    timestamp: number;
    outcome: 'success';
    phase: 'responseStreaming';
    fetcher: FetcherId;
    hostname: string;
    bytesReceived: number;
} | {
    internalId: string;
    timestamp: number;
    outcome: 'error' | 'cancel';
    phase: 'requestResponse';
    fetcher: FetcherId;
    hostname: string;
    reason: any;
} | {
    internalId: string;
    timestamp: number;
    outcome: 'error' | 'cancel';
    phase: 'responseStreaming';
    fetcher: FetcherId;
    hostname: string;
    reason: any;
    bytesReceived: number;
};
export type ReportFetchEvent = (outcome: FetchEvent) => void;
export interface FetchTelemetryEvent {
    callSite: string;
    hostname: string;
    latencyMs: number;
    statusCode: number | undefined;
    success: boolean;
}
/** A basic version of http://developer.mozilla.org/en-US/docs/Web/API/Response */
export declare class Response {
    readonly status: number;
    readonly statusText: string;
    readonly headers: IHeaders;
    readonly fetcher: FetcherId;
    private readonly _reportEvent;
    private readonly _internalId;
    private readonly _hostname;
    ok: boolean;
    readonly body: DestroyableStream<Uint8Array>;
    private _bytesReceived;
    get bytesReceived(): number;
    constructor(status: number, statusText: string, headers: IHeaders, body: ReadableStream<Uint8Array> | null, fetcher: FetcherId, _reportEvent: ReportFetchEvent, _internalId: string, _hostname: string);
    static fromText(status: number, statusText: string, headers: IHeaders, body: string, fetcher: FetcherId): Response;
    text(): Promise<string>;
    json(): Promise<any>;
}
export type FetcherId = 'electron-fetch' | 'node-fetch' | 'node-http' | 'test-stub' | 'helix-fetch';
/** These are the options we currently use, for ease of reference. */
export interface FetchOptions {
    /** Identifies the call site for telemetry tracking. Use {@link NO_FETCH_TELEMETRY} to suppress. */
    callSite: string;
    headers?: {
        [name: string]: string;
    };
    body?: string;
    timeout?: number;
    /**
     * If `json` is provided, it will be stringified using `JSON.stringify` and sent as the body with
     * the `Content-Type` header set to `application/json`.
     */
    json?: unknown;
    method?: 'GET' | 'POST' | 'PUT';
    signal?: IAbortSignal;
    retryFallbacks?: boolean;
    expectJSON?: boolean;
    useFetcher?: FetcherId;
    suppressIntegrationId?: boolean;
}
export interface PaginationOptions<T> extends FetchOptions {
    pageSize?: number;
    startPage?: number;
    getItemsFromResponse: (data: any) => T[];
    buildUrl: (baseUrl: string, pageSize: number, page: number) => string;
}
export interface WebSocketConnectOptions {
    headers?: {
        [name: string]: string;
    };
}
export interface WebSocketConnection {
    readonly webSocket: WebSocket;
    readonly responseHeaders: IHeaders;
    readonly responseStatusCode: number | undefined;
    readonly responseStatusText: string | undefined;
    readonly networkError: Error | undefined;
}
export interface IAbortSignal {
    readonly aborted: boolean;
    addEventListener(type: 'abort', listener: (this: AbortSignal) => void): void;
    removeEventListener(type: 'abort', listener: (this: AbortSignal) => void): void;
}
export interface IAbortController {
    readonly signal: IAbortSignal;
    abort(): void;
}
export interface IHeaders extends Iterable<[string, string]> {
    get(name: string): string | null;
}
export declare class HeadersImpl implements IHeaders {
    private readonly _record;
    constructor(_record: Readonly<Record<string, string | string[] | undefined>>);
    static fromMap(map: ReadonlyMap<string, string>): HeadersImpl;
    get(name: string): string | null;
    [Symbol.iterator](): Iterator<[string, string]>;
}
/**
 * Wraps a ReadableStream to allow cancellation even while a `for await` loop
 * holds the stream locked. Use `destroy()` to safely cancel from an external
 * callback (e.g., `onReturn`) - it cancels through the reader if locked.
 *
 * When `pipeThrough()` is called, destroy() will forward to the piped stream.
 */
export declare class DestroyableStream<T> implements AsyncIterable<T> {
    private readonly stream;
    private reader;
    private pipedHead;
    constructor(stream: ReadableStream<T>);
    /**
     * Returns the underlying ReadableStream for APIs that require it
     * (e.g., Readable.fromWeb). Use with caution as operations on the
     * returned stream bypass the DestroyableStream's reader tracking.
     */
    toReadableStream(): ReadableStream<T>;
    /**
     * Pipes this stream through a transform stream.
     * Returns a new DestroyableStream wrapping the transformed stream.
     * Calling destroy() on this stream will forward to the piped stream.
     */
    pipeThrough<U>(transform: {
        readable: ReadableStream<U>;
        writable: WritableStream<T>;
    }): DestroyableStream<U>;
    [Symbol.asyncIterator](): AsyncGenerator<T, void, undefined>;
    destroy(): Promise<void>;
}
export declare function jsonVerboseError(resp: Response): Promise<any>;
export declare function isAbortError(e: any): boolean;
export declare function safeGetHostname(url: string): string;
//# sourceMappingURL=fetcherService.d.ts.map