import { Pattern } from 'fast-glob';

type PopulateParams = Record<string, {
    value?: string[] | string | Record<string, string[] | string>;
    hashes?: string[];
    queries?: Record<string, string>[];
}[]>;
type ScanOptions = {
    /**
     * path of pages (e.g. `/docs/page.tsx`)
     *
     * App Router format only
     **/
    pages?: string[];
    cwd?: string;
    populate?: PopulateParams;
    meta?: Record<string, UrlMeta>;
    extensions?: string[];
};
type ScanResult = {
    urls: Map<string, UrlMeta>;
    fallbackUrls: {
        url: RegExp;
        meta: UrlMeta;
    }[];
};
type UrlMeta = {
    hashes?: string[];
    queries?: Record<string, string>[];
};
declare function scanURLs({ preset, ...options }?: ScanOptions & {
    /**
     * @default next
     */
    preset?: 'next' | 'astro' | 'nuxt';
}): Promise<ScanResult>;

type PathToUrl = (path: string) => string;
declare function readFileFromPath(file: string, pathToUrl?: PathToUrl): Promise<FileObject & {
    data?: object;
}>;
declare function readFiles(patterns: Pattern | Pattern[], options?: Partial<{
    pathToUrl?: PathToUrl;
}>): Promise<FileObject[]>;

type ValidateError = {
    file: string;
    detected: DetectedError[];
};
type ErrorReason = 'not-found' | 'invalid-fragment' | 'invalid-query';
type DetectedError = [
    url: string,
    line: number,
    column: number,
    reason: ErrorReason | Error
];
type ValidateConfig = {
    /**
     * Base URL to resolve relative URLs
     */
    baseUrl?: string;
    /**
     * Base directory to resolve relative file paths
     */
    baseDir?: string;
    /**
     * Available URLs (including hashes and query parameters)
     */
    scanned: ScanResult;
    /**
     * don't validate the fragment/hash of URLs
     *
     * @defaultValue false
     */
    ignoreFragment?: boolean;
    /**
     * don't validate the query of URLs
     *
     * @defaultValue false
     */
    ignoreQuery?: boolean;
    /**
     * Check external urls
     *
     * @defaultValue false
     */
    checkExternal?: boolean;
    /**
     * Generate url for file paths.
     *
     * Required for relative url/file path detection.
     */
    pathToUrl?: PathToUrl;
    /**
     * Allowed hrefs, can be:
     * - a list of hrefs
     * - a function that returns `true` for allowed href
     */
    whitelist?: string[] | ((url: string) => boolean);
    /**
     * Determinate the type of pathname
     */
    determinatePathname?: (pathname: string, config: ValidateConfig) => Awaitable<PathnameType>;
};
type PathnameType = 'url' | 'relative-file-path' | 'relative-url';
type Awaitable<T> = T | Promise<T>;
type FileObject = {
    path: string;
    content: string;
    data?: object;
    /**
     * URL of page, required for relative url detection
     */
    url?: string;
};
/**
 * Validate markdown files
 *
 * @param files - file paths or file objects
 * @param config - configurations
 */
declare function validateFiles(files: (string | FileObject)[], config: ValidateConfig): Promise<ValidateError[]>;
declare function validateMarkdown(content: string, config: ValidateConfig): Promise<DetectedError[]>;
declare function detect(href: string, config: ValidateConfig): Promise<ErrorReason | undefined>;

/**
 * Print validation errors
 */
declare function printErrors(errors: ValidateError[], throwError?: boolean): void;

export { type DetectedError, type ErrorReason, type FileObject, type PathToUrl, type PopulateParams, type ScanOptions, type ScanResult, type UrlMeta, type ValidateConfig, type ValidateError, detect, printErrors, readFileFromPath, readFiles, scanURLs, validateFiles, validateMarkdown };
