@react-md/form
Version:
This package is for creating all the different form input types.
405 lines • 15 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSplitFileUploads = exports.getFileParser = exports.isMediaFile = exports.isVideoFile = exports.isAudioFile = exports.isImageFile = exports.isTextFile = exports.validateFiles = exports.isValidFileName = exports.isFileExtensionError = exports.isFileSizeError = exports.isTooManyFilesError = exports.isFileAccessError = exports.isGenericFileError = exports.FileExtensionError = exports.FileSizeError = exports.TooManyFilesError = exports.GenericFileError = exports.FileAccessError = void 0;
var nanoid_1 = require("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.
*
* @remarks \@since 2.9.0
*/
var FileAccessError = /** @class */ (function (_super) {
__extends(FileAccessError, _super);
/**
*
* @param message - An optional message for the error.
*/
function FileAccessError(message) {
var _this = _super.call(this, message) || this;
_this.key = (0, nanoid_1.nanoid)();
_this.name = "FileAccessError";
return _this;
}
return FileAccessError;
}(Error));
exports.FileAccessError = FileAccessError;
/**
* An error that just requires a `File` to be passed as the first argument.
*
* @remarks \@since 2.9.0
*/
var GenericFileError = /** @class */ (function (_super) {
__extends(GenericFileError, _super);
/**
*
* @param files - A list of files that caused the error.
* @param reason - An optional reason for the error
*/
function GenericFileError(files, reason) {
var _this = _super.call(this, "Invalid files") || this;
_this.files = files;
_this.reason = reason;
_this.key = (0, nanoid_1.nanoid)();
_this.name = "GenericFileError";
return _this;
}
return GenericFileError;
}(Error));
exports.GenericFileError = GenericFileError;
/**
* An error that is created during the upload process if the number of files
* exceeds the {@link FileUploadOptions.maxFiles} amount.
*
* @remarks \@since 2.9.0
*/
var TooManyFilesError = /** @class */ (function (_super) {
__extends(TooManyFilesError, _super);
/**
*
* @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.
*/
function TooManyFilesError(files, limit) {
var _this = _super.call(this, files, "file limit") || this;
_this.limit = limit;
_this.name = "TooManyFilesError";
return _this;
}
return TooManyFilesError;
}(GenericFileError));
exports.TooManyFilesError = 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}
*
* @remarks \@since 2.9.0
*/
var FileSizeError = /** @class */ (function (_super) {
__extends(FileSizeError, _super);
/**
*
* @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
*/
function FileSizeError(files, type, limit) {
var _this = _super.call(this, files, "file size") || this;
_this.type = type;
_this.limit = limit;
_this.name = "FileSizeError";
return _this;
}
return FileSizeError;
}(GenericFileError));
exports.FileSizeError = 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}.
*
* @remarks \@since 2.9.0
*/
var FileExtensionError = /** @class */ (function (_super) {
__extends(FileExtensionError, _super);
/**
*
* @param files - The file that caused the error
* @param extensions - The allowed list of file extensions
*/
function FileExtensionError(files, extensions) {
var _this = _super.call(this, files, "extension") || this;
_this.extensions = extensions;
_this.name = "FileExtensionError";
return _this;
}
return FileExtensionError;
}(GenericFileError));
exports.FileExtensionError = 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}
*/
function isGenericFileError(error) {
return "name" in error && error.name === "GenericFileError";
}
exports.isGenericFileError = isGenericFileError;
/**
* 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}
*/
function isFileAccessError(error) {
return "name" in error && error.name === "FileAccessError";
}
exports.isFileAccessError = isFileAccessError;
/**
* 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}
*/
function isTooManyFilesError(error) {
return "name" in error && error.name === "TooManyFilesError";
}
exports.isTooManyFilesError = isTooManyFilesError;
/**
* 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}
*/
function isFileSizeError(error) {
return "name" in error && error.name === "FileSizeError";
}
exports.isFileSizeError = isFileSizeError;
/**
* 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}
*/
function isFileExtensionError(error) {
return "name" in error && error.name === "FileExtensionError";
}
exports.isFileExtensionError = isFileExtensionError;
/**
*
* @defaultValue `matcher?.test(file.name) ?? true`
* @remarks \@since 3.1.0
*/
var isValidFileName = function (file, matcher) { var _a; return (_a = matcher === null || matcher === void 0 ? void 0 : matcher.test(file.name)) !== null && _a !== void 0 ? _a : true; };
exports.isValidFileName = isValidFileName;
/**
* 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}
* @remarks \@since 2.9.0
*/
function validateFiles(files, _a) {
var maxFiles = _a.maxFiles, extensions = _a.extensions, minFileSize = _a.minFileSize, maxFileSize = _a.maxFileSize, totalBytes = _a.totalBytes, totalFiles = _a.totalFiles, totalFileSize = _a.totalFileSize, isValidFileName = _a.isValidFileName;
var errors = [];
var pending = [];
var extraFiles = [];
var extensionRegExp = extensions.length > 0
? new RegExp("\\.(".concat(extensions.join("|"), ")$"), "i")
: undefined;
var maxFilesReached = maxFiles > 0 && totalFiles >= maxFiles;
var remainingBytes = totalFileSize - totalBytes;
var extensionErrors = [];
var minErrors = [];
var maxErrors = [];
var totalSizeErrors = [];
for (var i = 0; i < files.length; i += 1) {
var file = files[i];
var valid = true;
var size = file.size;
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: pending, errors: errors };
}
exports.validateFiles = validateFiles;
/**
* This will first check if the mime-type of the file starts with `text/` and
* fallback to checking a few file names or extensions that should be considered
* text.
*
* This function is not guaranteed to be 100% correct and is only useful if
* trying to generate a preview of files uploaded to the browser.
*
* @param file - The file to check
* @returns `true` if the file should be considered as a text-content file.
* @remarks \@since 2.9.0
*/
function isTextFile(file) {
return /\.((j|t)sx?|json|lock|hbs|ya?ml|log|txt|md)$/i.test(file.name);
}
exports.isTextFile = isTextFile;
/**
* This will first check if the mime-type of the file starts with `text\/` and
* fallback to checking a few file names or extensions that should be considered
* text.
*
* This function is not guaranteed to be 100% correct and is only useful if
* trying to generate a preview of files uploaded to the browser.
*
* @param file - The file to check
* @returns `true` if the file should be considered as a text content file.
* @remarks \@since 2.9.0
*/
function isImageFile(file) {
return /\.(a?png|avif|svg|tiff|gifv?|jpe?g)/i.test(file.name);
}
exports.isImageFile = isImageFile;
/**
* This will first check if the mime-type of the file starts with `audio/` and
* fallback to checking a few file names or extensions that should be considered
* audio.
*
* This function is not guaranteed to be 100% correct and is only useful if
* trying to generate a preview of files uploaded to the browser.
*
* @param file - The file to check
* @returns `true` if the file should be considered as a audio content file.
* @remarks \@since 2.9.0
*/
function isAudioFile(file) {
return /\.(mp3|wav|ogg|m4p|flac)$/i.test(file.name);
}
exports.isAudioFile = isAudioFile;
/**
* This will first check if the mime-type of the file starts with `video/` and
* fallback to checking a few file names or extensions that should be considered
* video.
*
* This function is not guaranteed to be 100% correct and is only useful if
* trying to generate a preview of files uploaded to the browser.
*
* @param file - The file to check
* @returns `true` if the file should be considered as a video content file.
* @remarks \@since 2.9.0
*/
function isVideoFile(file) {
return /\.(mkv|mpe?g|mov|avi|flv|webm|mp4)$/i.test(file.name);
}
exports.isVideoFile = isVideoFile;
/**
* This function is not guaranteed to be 100% correct and is only useful if
* trying to generate a preview of files uploaded to the browser.
*
* @param file - The file to check
* @returns `true` if the file matches an image, audio, or video file.
* @remarks \@since 2.9.0
*/
function isMediaFile(file) {
return isImageFile(file) || isAudioFile(file) || isVideoFile(file);
}
exports.isMediaFile = isMediaFile;
/**
* This function will attempt to read:
* - media (image, audio, and video) files as a data url so they can be
* previewed in `<img>`, `<audio>`, and `<video>` tags
* - text files as plain text
* - everything else as an `ArrayBuffer` which can be manually converted into a
* data url if needed with `URL.createObjectURL`
*
* @remarks \@since 2.9.0
*/
var getFileParser = function (file) {
if (isMediaFile(file)) {
return "readAsDataURL";
}
if (isTextFile(file)) {
return "readAsText";
}
return "readAsArrayBuffer";
};
exports.getFileParser = getFileParser;
/**
* This util will split all the current upload stats by status.
*
* @param stats - The {@link FileUploadStats} list generally returned by the
* {@link useFileUpload} hook.
* @returns the {@link SplitFileUploads}.
* @remarks \@since 2.9.0
*/
function getSplitFileUploads(stats) {
var pending = [];
var uploading = [];
var complete = [];
stats.forEach(function (stat) {
if (stat.status === "pending") {
pending.push(stat);
}
else if (stat.status === "uploading") {
uploading.push(stat);
}
else if (stat.status === "complete") {
complete.push(stat);
}
else {
/* istanbul ignore next */
throw new Error("Invalid upload stat");
}
});
return { pending: pending, uploading: uploading, complete: complete };
}
exports.getSplitFileUploads = getSplitFileUploads;
//# sourceMappingURL=utils.js.map