type RateLimiterFn = () => Promise<number>;
type RateLimiters = Record<string, RateLimiterFn | {
    method: string;
    limit: RateLimiterFn;
}>;
type RateLimitOptions = Record<string, number | {
    method: string;
    limit: number;
}>;
type ResponseBodyTypes = Record<string, unknown> | Record<string, unknown>[] | ReadableStream | Blob | string | string[] | number | void | null;
interface FormattedResponse<T extends ResponseBodyTypes = ResponseBodyTypes> {
    body: T;
    headers: Record<string, string>;
    status: number;
}
interface Constructable<T = any> {
    new (...args: any[]): T;
}
type ResourceOptions = {
    headers: {
        [header: string]: string;
    };
    authHeaders: {
        [authHeader: string]: () => Promise<string>;
    };
    url: string;
    rejectUnauthorized: boolean;
    rateLimits?: RateLimitOptions;
};
type DefaultRequestOptions = {
    body?: FormData | Record<string, unknown>;
    searchParams?: Record<string, unknown>;
    sudo?: string | number;
    method?: string;
    asStream?: boolean;
    signal?: AbortSignal;
};
type RequestOptions = {
    headers?: Record<string, string>;
    timeout?: number;
    method?: string;
    searchParams?: string;
    prefixUrl?: string;
    body?: string | FormData;
    asStream?: boolean;
    signal?: AbortSignal;
    rateLimiters?: Record<string, RateLimiterFn>;
};
interface RequesterType {
    get<T extends ResponseBodyTypes>(endpoint: string, options?: DefaultRequestOptions): Promise<FormattedResponse<T>>;
    post<T extends ResponseBodyTypes>(endpoint: string, options?: DefaultRequestOptions): Promise<FormattedResponse<T>>;
    put<T extends ResponseBodyTypes>(endpoint: string, options?: DefaultRequestOptions): Promise<FormattedResponse<T>>;
    patch<T extends ResponseBodyTypes>(endpoint: string, options?: DefaultRequestOptions): Promise<FormattedResponse<T>>;
    delete<T extends ResponseBodyTypes>(endpoint: string, options?: DefaultRequestOptions): Promise<FormattedResponse<T>>;
}
type RequestHandlerFn<T extends ResponseBodyTypes = ResponseBodyTypes> = (endpoint: string, options?: Record<string, unknown>) => Promise<FormattedResponse<T>>;
declare function generateRateLimiterFn(limit: number, interval: number): () => Promise<number>;
declare function formatQuery(params?: Record<string, unknown>): string;
type OptionsHandlerFn = (serviceOptions: ResourceOptions, requestOptions: RequestOptions) => Promise<RequestOptions>;
declare function defaultOptionsHandler(resourceOptions: ResourceOptions, { body, searchParams, sudo, signal, asStream, method, }?: DefaultRequestOptions): Promise<RequestOptions>;
declare function createRateLimiters(rateLimitOptions?: RateLimitOptions): RateLimiters;
declare function createRequesterFn(optionsHandler: OptionsHandlerFn, requestHandler: RequestHandlerFn): (serviceOptions: ResourceOptions) => RequesterType;
declare function presetResourceArguments<T extends Record<string, Constructable>>(resources: T, customConfig?: Record<string, unknown>): T;
declare function getMatchingRateLimiter(endpoint: string, rateLimiters?: RateLimiters, method?: string): RateLimiterFn;

interface RootResourceOptions<C> {
    requesterFn?: (resourceOptions: ResourceOptions) => RequesterType;
    host?: string;
    prefixUrl?: string;
    rejectUnauthorized?: boolean;
    camelize?: C;
    queryTimeout?: number | null;
    sudo?: string | number;
    profileToken?: string;
    profileMode?: 'execution' | 'memory';
    rateLimits?: RateLimitOptions;
}
type GitlabToken = string | (() => Promise<string>);
interface BaseRequestOptionsWithOAuthToken<C> extends RootResourceOptions<C> {
    oauthToken: GitlabToken;
}
interface BaseRequestOptionsWithAccessToken<C> extends RootResourceOptions<C> {
    token: GitlabToken;
}
interface BaseRequestOptionsWithJobToken<C> extends RootResourceOptions<C> {
    jobToken: GitlabToken;
}
type BaseResourceOptions<C> = BaseRequestOptionsWithOAuthToken<C> | BaseRequestOptionsWithAccessToken<C> | BaseRequestOptionsWithJobToken<C>;
declare class BaseResource<C extends boolean = false> {
    readonly url: string;
    readonly requester: RequesterType;
    readonly queryTimeout: number | null;
    readonly headers: {
        [header: string]: string;
    };
    readonly authHeaders: {
        [authHeader: string]: () => Promise<string>;
    };
    readonly camelize: C | undefined;
    readonly rejectUnauthorized: boolean;
    constructor({ sudo, profileToken, camelize, requesterFn, profileMode, host, prefixUrl, rejectUnauthorized, queryTimeout, rateLimits, ...tokens }: BaseResourceOptions<C>);
}

declare class GitbeakerRequestError extends Error {
    readonly cause?: {
        description: string;
        request: Request;
        response: Response;
    };
    constructor(message: string, options?: {
        cause?: {
            description: string;
            request: Request;
            response: Response;
        };
    });
}
declare class GitbeakerTimeoutError extends Error {
    constructor(message: string, options?: ErrorOptions);
}
declare class GitbeakerRetryError extends Error {
    constructor(message: string, options?: ErrorOptions);
}

export { type BaseRequestOptionsWithAccessToken, type BaseRequestOptionsWithJobToken, type BaseRequestOptionsWithOAuthToken, BaseResource, type BaseResourceOptions, type Constructable, type DefaultRequestOptions, type FormattedResponse, GitbeakerRequestError, GitbeakerRetryError, GitbeakerTimeoutError, type GitlabToken, type OptionsHandlerFn, type RateLimitOptions, type RateLimiterFn, type RateLimiters, type RequestHandlerFn, type RequestOptions, type RequesterType, type ResourceOptions, type ResponseBodyTypes, type RootResourceOptions, createRateLimiters, createRequesterFn, defaultOptionsHandler, formatQuery, generateRateLimiterFn, getMatchingRateLimiter, presetResourceArguments };
