import { Promisable } from 'type-fest';
export { IsEqual, IsNever, PartialDeep, Promisable } from 'type-fest';
export { group, guard, mapEntries, mapValues, omit } from 'radash';

type MaybeOptionalOptions<TOptions> = Record<never, never> extends TOptions ? [options?: TOptions] : [options: TOptions];
declare function resolveMaybeOptionalOptions<T>(rest: MaybeOptionalOptions<T>): T;

declare function toArray<T>(value: T): T extends readonly any[] ? T : Exclude<T, undefined | null>[];
declare function splitInHalf<T>(arr: readonly T[]): [T[], T[]];

type AnyFunction = (...args: any[]) => any;
declare function once<T extends () => any>(fn: T): () => ReturnType<T>;

type OmitChainMethodDeep<T extends object, K extends keyof any> = {
    [P in keyof Omit<T, K>]: T[P] extends AnyFunction ? ((...args: Parameters<T[P]>) => OmitChainMethodDeep<ReturnType<T[P]>, K>) : T[P];
};

type SetOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type IntersectPick<T, U> = Pick<T, keyof T & keyof U>;
type PromiseWithError<T, TError> = Promise<T> & {
    __error?: {
        type: TError;
    };
};
/**
 * The place where you can config the orpc types.
 *
 * - `throwableError` the error type that represent throwable errors should be `Error` or `null | undefined | {}` if you want more strict.
 */
interface Registry {
}
type ThrowableError = Registry extends {
    throwableError: infer T;
} ? T : Error;

type InterceptableOptions = Record<string, any>;
type InterceptorOptions<TOptions extends InterceptableOptions, TResult, TError> = Omit<TOptions, 'next'> & {
    next(options?: TOptions): PromiseWithError<TResult, TError>;
};
type Interceptor<TOptions extends InterceptableOptions, TResult, TError> = (options: InterceptorOptions<TOptions, TResult, TError>) => Promisable<TResult>;
/**
 * Can used for interceptors or middlewares
 */
declare function onStart<T, TOptions extends {
    next(): any;
}, TRest extends any[]>(callback: NoInfer<(options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
/**
 * Can used for interceptors or middlewares
 */
declare function onSuccess<T, TOptions extends {
    next(): any;
}, TRest extends any[]>(callback: NoInfer<(result: Awaited<ReturnType<TOptions['next']>>, options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
/**
 * Can used for interceptors or middlewares
 */
declare function onError<T, TOptions extends {
    next(): any;
}, TRest extends any[]>(callback: NoInfer<(error: ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError, options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
type OnFinishState<TResult, TError> = [error: TError, data: undefined, isSuccess: false] | [error: null, data: TResult, isSuccess: true];
/**
 * Can used for interceptors or middlewares
 */
declare function onFinish<T, TOptions extends {
    next(): any;
}, TRest extends any[]>(callback: NoInfer<(state: OnFinishState<Awaited<ReturnType<TOptions['next']>>, ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError>, options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
declare function intercept<TOptions extends InterceptableOptions, TResult, TError>(interceptors: Interceptor<TOptions, TResult, TError>[], options: NoInfer<TOptions>, main: NoInfer<(options: TOptions) => Promisable<TResult>>): Promise<TResult>;

declare function isAsyncIteratorObject(maybe: unknown): maybe is AsyncIteratorObject<any, any, any>;

declare function parseEmptyableJSON(text: string | null | undefined): unknown;
declare function stringifyJSON<T>(value: T): undefined extends T ? undefined | string : string;

type Segment = string | number;
declare function findDeepMatches(check: (value: unknown) => boolean, payload: unknown, segments?: Segment[], maps?: Segment[][], values?: unknown[]): {
    maps: Segment[][];
    values: unknown[];
};
/**
 * Check if the value is an object even it created by `Object.create(null)` or more tricky way.
 */
declare function isObject(value: unknown): value is Record<PropertyKey, unknown>;
/**
 * Check if the value satisfy a `object` type in typescript
 */
declare function isTypescriptObject(value: unknown): value is object & Record<PropertyKey, unknown>;
declare function clone<T>(value: T): T;
declare function get(object: object, path: readonly string[]): unknown;

type Value<T, TArgs extends any[] = []> = T | ((...args: TArgs) => Promisable<T>);
declare function value<T, TArgs extends any[]>(value: Value<T, TArgs>, ...args: NoInfer<TArgs>): Promise<T extends Value<infer U, any> ? U : never>;

export { clone, findDeepMatches, get, intercept, isAsyncIteratorObject, isObject, isTypescriptObject, onError, onFinish, onStart, onSuccess, once, parseEmptyableJSON, resolveMaybeOptionalOptions, splitInHalf, stringifyJSON, toArray, value };
export type { AnyFunction, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OmitChainMethodDeep, OnFinishState, PromiseWithError, Registry, Segment, SetOptional, ThrowableError, Value };
