import { Packument } from 'pacote';

type SortKey = 'time' | 'diff' | 'name';
type SortOrder = 'asc' | 'desc';
type SortOption = `${SortKey}-${SortOrder}`;

type RangeMode = 'default' | 'major' | 'minor' | 'patch' | 'latest' | 'newest';
type PackageMode = Omit<RangeMode, 'default'> | 'ignore';
type DepType = 'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies' | 'packageManager' | 'pnpm.overrides' | 'resolutions' | 'overrides';
declare const DependenciesTypeShortMap: {
    dependencies: string;
    devDependencies: string;
    peerDependencies: string;
    optionalDependencies: string;
    packageManager: string;
    'pnpm.overrides': string;
    resolutions: string;
    overrides: string;
};
interface RawDep {
    name: string;
    currentVersion: string;
    source: DepType;
    update: boolean;
    parents?: string[];
}
type DiffType = 'major' | 'minor' | 'patch' | 'error' | null;
interface PackageData {
    tags: Record<string, string>;
    versions: string[];
    time?: Record<string, string>;
    raw?: Packument;
    error?: Error | string;
}
interface ResolvedDepChange extends RawDep {
    latestVersionAvailable?: string;
    targetVersion: string;
    targetVersionTime?: string;
    currentVersionTime?: string;
    diff: DiffType;
    pkgData: PackageData;
    resolveError?: Error | string | null;
    interactiveChecked?: boolean;
    aliasName?: string;
}
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
interface CommonOptions {
    cwd?: string;
    recursive?: boolean;
    ignorePaths?: string | string[];
    include?: string | string[];
    exclude?: string | string[];
    loglevel?: LogLevel;
    failOnOutdated?: boolean;
    silent?: boolean;
    /**
     * Fields in package.json to be checked
     * By default all fields will be checked
     */
    depFields?: DepFieldOptions;
    /**
     * Bypass cache
     */
    force?: boolean;
    /**
     * Override bumping mode for specific dependencies
     */
    packageMode?: {
        [name: string]: PackageMode;
    };
}
interface UsageOptions extends CommonOptions {
    detail?: boolean;
    recursive?: true;
}
type DepFieldOptions = Partial<Record<DepType, boolean>>;
interface CheckOptions extends CommonOptions {
    mode?: RangeMode;
    write?: boolean;
    all?: boolean;
    sort?: SortOption;
    interactive?: boolean;
    install?: boolean;
    update?: boolean;
    global?: boolean;
    /**
     * include locked dependencies & devDependencies
     * @default false
     * @description exclude the locked deps/devDeps by default
     */
    includeLocked?: boolean;
}
interface PackageMeta {
    /**
     * Package name
     */
    name: string;
    /**
     * Package version
     */
    version: string;
    /**
     * Absolute filepath
     */
    filepath: string;
    /**
     * Relative filepath to the root project
     */
    relative: string;
    /**
     * Raw package.json Object
     */
    raw: any;
    /**
     * Dependencies
     */
    deps: RawDep[];
    /**
     * Resolved dependencies
     */
    resolved: ResolvedDepChange[];
    interactiveChecked?: boolean;
}
type DependencyFilter = (dep: RawDep) => boolean | Promise<boolean>;
type DependencyResolvedCallback = (packageName: string | null, depName: string, progress: number, total: number) => void;
interface InteractiveContext {
    isSelected: (dep: RawDep) => boolean;
}

declare function resolveDependency(raw: RawDep, options: CheckOptions, filter?: DependencyFilter): Promise<ResolvedDepChange>;
declare function resolveDependencies(deps: RawDep[], options: CheckOptions, filter?: DependencyFilter, progressCallback?: (name: string, counter: number, total: number) => void): Promise<ResolvedDepChange[]>;
declare function resolvePackage(pkg: PackageMeta, options: CheckOptions, filter?: DependencyFilter, progress?: DependencyResolvedCallback): Promise<PackageMeta>;

declare function writePackage(pkg: PackageMeta, options: CommonOptions): Promise<void>;
declare function loadPackage(relative: string, options: CommonOptions, shouldUpdate: (name: string) => boolean): Promise<PackageMeta>;
declare function loadPackages(options: CommonOptions): Promise<PackageMeta[]>;

declare function parseDependencies(pkg: any, type: DepType, shouldUpdate: (name: string) => boolean): RawDep[];
declare function dumpDependencies(deps: ResolvedDepChange[], type: DepType): Record<string, any>;

interface CheckEventCallbacks {
    afterPackagesLoaded?: (pkgs: PackageMeta[]) => void;
    beforePackageStart?: (pkg: PackageMeta) => void;
    afterPackageEnd?: (pkg: PackageMeta) => void;
    beforePackageWrite?: (pkg: PackageMeta) => boolean | Promise<boolean>;
    afterPackagesEnd?: (pkgs: PackageMeta[]) => void;
    afterPackageWrite?: (pkg: PackageMeta) => void;
    onDependencyResolved?: DependencyResolvedCallback;
}
declare function CheckPackages(options: CheckOptions, callbacks?: CheckEventCallbacks): Promise<{
    packages: PackageMeta[];
}>;

declare function defineConfig(config: Partial<CheckOptions>): Partial<CheckOptions>;

export { type CheckOptions, CheckPackages, type CommonOptions, type DepFieldOptions, type DepType, DependenciesTypeShortMap, type DependencyFilter, type DependencyResolvedCallback, type DiffType, type InteractiveContext, type LogLevel, type PackageData, type PackageMeta, type PackageMode, type RangeMode, type RawDep, type ResolvedDepChange, type UsageOptions, defineConfig, dumpDependencies, loadPackage, loadPackages, parseDependencies, resolveDependencies, resolveDependency, resolvePackage, writePackage };
