/**
 * An error that will be created if a user tries dragging and dropping files
 * from a shared directory that they do not have access to. This error will not
 * occur much.
 *
 * @since 2.9.0
 */
export declare class FileAccessError extends Error {
    /**
     * A unique key generated by `nanoid` that can be used as a `React` key
     */
    key: string;
    /**
     *
     * @param message - An optional message for the error.
     */
    constructor(message?: string);
}
/**
 * An error that just requires a `File` to be passed as the first argument.
 *
 * @since 2.9.0
 */
export declare class GenericFileError extends Error {
    files: readonly File[];
    reason?: string | undefined;
    /**
     * A unique key generated by `nanoid` that can be used as a `React` key
     */
    key: string;
    /**
     *
     * @param files - A list of files that caused the error.
     * @param reason - An optional reason for the error
     */
    constructor(files: readonly File[], reason?: string | undefined);
}
/**
 * An error that is created during the upload process if the number of files
 * exceeds the {@link FileUploadOptions.maxFiles} amount.
 *
 * @since 2.9.0
 */
export declare class TooManyFilesError extends GenericFileError {
    limit: number;
    /**
     *
     * @param files - The list of files that could not be uploaded due to the file
     * limit defined.
     * @param limit - The max limit of files allowed.
     */
    constructor(files: readonly File[], limit: number);
}
/**
 * An error that will be created if a user tries to upload a file that
 * is either:
 * - less than the {@link FileValidationOptions.minFileSize}
 * - greater than the {@link FileValidationOptions.maxFileSize}
 * - including the file would be greater than the {@link FileValidationOptions.totalFileSize}
 *
 * @since 2.9.0
 */
export declare class FileSizeError extends GenericFileError {
    type: "min" | "max" | "total";
    limit: number;
    /**
     *
     * @param files - The list of files that have the file size error
     * @param type - The file size error type
     * @param limit - The number of bytes allowed based on the type
     */
    constructor(files: readonly File[], type: "min" | "max" | "total", limit: number);
}
/**
 * An error that will be created if a user tries to upload a file that does not
 * end with one of the {@link FileValidationOptions.extensions}.
 *
 * @since 2.9.0
 */
export declare class FileExtensionError extends GenericFileError {
    extensions: readonly string[];
    /**
     *
     * @param files - The file that caused the error
     * @param extensions - The allowed list of file extensions
     */
    constructor(files: readonly File[], extensions: readonly string[]);
}
/**
 * Mostly an internal type that is used to allow custom validation errors
 *
 * @since 2.9.0
 */
export type FileValidationError<E = GenericFileError> = FileAccessError | TooManyFilesError | FileSizeError | FileExtensionError | E;
/**
 * A simple type-guard that can be used to check if the
 * {@link FileValidationError} is the {@link GenericFileError} which can be
 * useful when displaying the errors to the user.
 *
 * @param error - The error to check
 * @returns true if the error is a {@link FileAccessError}
 */
export declare function isGenericFileError<CustomError extends object>(error: FileValidationError<CustomError>): error is GenericFileError;
/**
 * A simple type-guard that can be used to check if the
 * {@link FileValidationError} is the {@link FileAccessError} which can be
 * useful when displaying the errors to the user.
 *
 * @param error - The error to check
 * @returns true if the error is a {@link FileAccessError}
 */
export declare function isFileAccessError<CustomError extends object>(error: FileValidationError<CustomError>): error is FileAccessError;
/**
 * A simple type-guard that can be used to check if the
 * {@link FileValidationError} is the {@link TooManyFilesError} which can be
 * useful when displaying the errors to the user.
 *
 * @param error - The error to check
 * @returns true if the error is a {@link TooManyFilesError}
 */
export declare function isTooManyFilesError<CustomError extends object>(error: FileValidationError<CustomError>): error is TooManyFilesError;
/**
 * A simple type-guard that can be used to check if the
 * {@link FileValidationError} is the {@link FileSizeError} which can be
 * useful when displaying the errors to the user.
 *
 * @param error - The error to check
 * @returns true if the error is a {@link FileSizeError}
 */
export declare function isFileSizeError<CustomError extends object>(error: FileValidationError<CustomError>): error is FileSizeError;
/**
 * A simple type-guard that can be used to check if the
 * {@link FileValidationError} is the {@link FileExtensionError} which can be
 * useful when displaying the errors to the user.
 *
 * @param error - The error to check
 * @returns true if the error is a {@link FileExtensionError}
 */
export declare function isFileExtensionError<CustomError extends object>(error: FileValidationError<CustomError>): error is FileExtensionError;
/**
 * This function is used to determine if a file should be added to the
 * {@link FileExtensionError}. The default implementation should work for most
 * use cases except when files that do not have extensions can be uploaded. i.e.
 * LICENSE files.
 *
 * @param file - The file being checked
 * @param extensionRegExp - A regex that will only be defined if the
 * `extensions` list had at least one value.
 * @param extensions - The list of extensions allowed
 * @returns true if the file has a valid name.
 * @since 3.1.0
 */
export type IsValidFileName = (file: File, extensionRegExp: RegExp | undefined, extensions: readonly string[]) => boolean;
/**
 *
 * @defaultValue `matcher?.test(file.name) ?? true`
 * @since 3.1.0
 */
export declare const isValidFileName: IsValidFileName;
/** @since 2.9.0 */
export interface FileValidationOptions {
    /**
     * If the number of files should be limited, set this value to a number
     * greater than `0`.
     *
     * Note: This still allows "infinite" files when set to `0` since the
     * `<input>` element should normally be set to `disabled` if files should not
     * be able to be uploaded.
     *
     * @defaultValue `-1`
     */
    maxFiles?: number;
    /**
     * An optional minimum file size to enforce for each file. This will only be
     * used when it is greater than `0`.
     *
     * @defaultValue `-1`
     */
    minFileSize?: number;
    /**
     * An optional maximum file size to enforce for each file. This will only be
     * used when it is greater than `0`.
     *
     * @defaultValue `-1`
     */
    maxFileSize?: number;
    /**
     * An optional list of extensions to enforce when uploading files.
     *
     * Note: The extensions and file names will be compared ignoring case.
     *
     * @example Only Allow Images
     * ```ts
     * const extensions = ["png", "jpeg", "jpg", "gif"];
     * ```
     */
    extensions?: readonly string[];
    /** {@inheritDoc IsValidFileName} */
    isValidFileName?: IsValidFileName;
    /**
     * An optional total file size to enforce when the {@link maxFiles} option is
     * not set to `1`.
     *
     * @defaultValue `-1`
     */
    totalFileSize?: number;
}
/** @since 2.9.0 */
export interface FilesValidationOptions extends Required<FileValidationOptions> {
    /**
     * The total number of bytes in the {@link FileUploadHookReturnValue.stats}
     * list. This is really just:
     *
     * ```ts
     * const totalBytes = stats.reduce((total, stat) => total + stat.file.size, 0);
     * ```
     */
    totalBytes: number;
    /**
     * The total number of files in the {@link FileUploadHookReturnValue.stats}.
     */
    totalFiles: number;
}
/**
 * @since 2.9.0
 */
export interface ValidatedFilesResult<CustomError> {
    /**
     * A filtered list of files that have been validated and can be queued for the
     * upload process.
     */
    pending: readonly File[];
    /**
     * A list of {@link FileValidationError} that occurred during the validation
     * step.
     *
     * Note: If an error has occurred, the file **should not** be added to the
     * {@link pending} list of files.
     */
    errors: readonly FileValidationError<CustomError>[];
}
/**
 * This function will be called whenever a file has been uploaded by the user
 * either through an `<input type="file">` or drag and drop behavior.
 *
 * @example Simple Example
 * ```ts
 * const validateFiles: FilesValidator = (files, options) => {
 *   const invalid: File[] = [];
 *   const pending: File[] = [];
 *   for (const file of files) {
 *     if (!/\.(jpe?g|svg|png)$/i.test(name)) {
 *       invalid.push(file);
 *     } else {
 *       pending.push(file);
 *     }
 *   }
 *
 *   const errors: FileValidationError[] = [];
 *   if (invalid.length) {
 *     errors.push(new GenericFileError(invalid))
 *   }
 *
 *   return { pending, errors };
 * };
 * ```
 *
 * @typeParam E - An optional custom file validation error.
 * @param files - The list of files to check
 * @param options - The {@link FilesValidationOptions}
 * @returns the {@link ValidatedFilesResult}
 * @see {@link validateFiles} for the default implementation
 * @since 2.9.0
 */
export type FilesValidator<CustomError = never> = (files: readonly File[], options: FilesValidationOptions) => ValidatedFilesResult<CustomError>;
/**
 * A pretty decent default implementation for validating files with the
 * {@link useFileUpload} that ensures the {@link FilesValidationOptions} are
 * enforced before allowing a file to be uploaded.
 *
 * @typeParam E - An optional custom file validation error.
 * @param files - The list of files to check
 * @param options - The {@link FilesValidationOptions}
 * @returns the {@link ValidatedFilesResult}
 * @since 2.9.0
 */
export declare function validateFiles<CustomError>(files: readonly File[], options: FilesValidationOptions): ValidatedFilesResult<CustomError>;
