function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
import { nanoid } from "nanoid";
/**
 * 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 class FileAccessError extends Error {
    /**
   *
   * @param message - An optional message for the error.
   */ constructor(message){
        super(message), /**
   * A unique key generated by `nanoid` that can be used as a `React` key
   */ _define_property(this, "key", void 0);
        this.key = nanoid();
        this.name = "FileAccessError";
    }
}
/**
 * An error that just requires a `File` to be passed as the first argument.
 *
 * @since 2.9.0
 */ export class GenericFileError extends Error {
    /**
   *
   * @param files - A list of files that caused the error.
   * @param reason - An optional reason for the error
   */ constructor(files, reason){
        super("Invalid files"), _define_property(this, "files", void 0), _define_property(this, "reason", void 0), /**
   * A unique key generated by `nanoid` that can be used as a `React` key
   */ _define_property(this, "key", void 0), this.files = files, this.reason = reason;
        this.key = nanoid();
        this.name = "GenericFileError";
    }
}
/**
 * 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 class TooManyFilesError extends GenericFileError {
    /**
   *
   * @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, limit){
        super(files, "file limit"), _define_property(this, "limit", void 0), this.limit = limit;
        this.name = "TooManyFilesError";
    }
}
/**
 * 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 class FileSizeError extends GenericFileError {
    /**
   *
   * @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, type, limit){
        super(files, "file size"), _define_property(this, "type", void 0), _define_property(this, "limit", void 0), this.type = type, this.limit = limit;
        this.name = "FileSizeError";
    }
}
/**
 * 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 class FileExtensionError extends GenericFileError {
    /**
   *
   * @param files - The file that caused the error
   * @param extensions - The allowed list of file extensions
   */ constructor(files, extensions){
        super(files, "extension"), _define_property(this, "extensions", void 0), this.extensions = extensions;
        this.name = "FileExtensionError";
    }
}
/**
 * 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 function isGenericFileError(error) {
    return "name" in error && error.name === "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 function isFileAccessError(error) {
    return "name" in error && error.name === "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 function isTooManyFilesError(error) {
    return "name" in error && error.name === "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 function isFileSizeError(error) {
    return "name" in error && error.name === "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 function isFileExtensionError(error) {
    return "name" in error && error.name === "FileExtensionError";
}
/**
 *
 * @defaultValue `matcher?.test(file.name) ?? true`
 * @since 3.1.0
 */ export const isValidFileName = (file, matcher)=>matcher?.test(file.name) ?? true;
/**
 * 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 function validateFiles(files, options) {
    const { maxFiles, extensions, minFileSize, maxFileSize, totalBytes, totalFiles, totalFileSize, isValidFileName } = options;
    const errors = [];
    const pending = [];
    const extraFiles = [];
    const extensionRegExp = extensions.length > 0 ? new RegExp(`\\.(${extensions.join("|")})$`, "i") : undefined;
    let maxFilesReached = maxFiles > 0 && totalFiles >= maxFiles;
    let remainingBytes = totalFileSize - totalBytes;
    const extensionErrors = [];
    const minErrors = [];
    const maxErrors = [];
    const totalSizeErrors = [];
    for(let i = 0; i < files.length; i += 1){
        const file = files[i];
        let valid = true;
        const { size } = file;
        if (!isValidFileName(file, extensionRegExp, extensions)) {
            valid = false;
            extensionErrors.push(file);
        }
        if (minFileSize > 0 && size < minFileSize) {
            valid = false;
            minErrors.push(file);
        }
        if (maxFileSize > 0 && size > maxFileSize) {
            valid = false;
            maxErrors.push(file);
        } else if (totalFileSize > 0 && remainingBytes - file.size < 0) {
            // don't want both errors displaying
            valid = false;
            totalSizeErrors.push(file);
        }
        if (maxFilesReached && valid) {
            extraFiles.push(file);
        } else if (!maxFilesReached && valid) {
            pending.push(file);
            remainingBytes -= file.size;
            maxFilesReached = maxFilesReached || maxFiles > 0 && totalFiles + pending.length >= maxFiles;
        }
    }
    if (extensionErrors.length) {
        errors.push(new FileExtensionError(extensionErrors, extensions));
    }
    if (minErrors.length) {
        errors.push(new FileSizeError(minErrors, "min", minFileSize));
    }
    if (maxErrors.length) {
        errors.push(new FileSizeError(maxErrors, "max", maxFileSize));
    }
    if (totalSizeErrors.length) {
        errors.push(new FileSizeError(totalSizeErrors, "total", totalFileSize));
    }
    if (extraFiles.length) {
        errors.push(new TooManyFilesError(extraFiles, maxFiles));
    }
    return {
        pending,
        errors
    };
}

//# sourceMappingURL=validation.js.map