@uploadcare/file-uploader
Version: 
Building blocks for Uploadcare products integration
112 lines (100 loc) • 2.96 kB
JavaScript
// @ts-check
import { browserInfo } from './browser-info.js';
import { stringToArray } from './stringToArray.js';
export const BASIC_IMAGE_WILDCARD = 'image/*';
export const BASIC_VIDEO_WILDCARD = 'video/*';
export const HEIC_IMAGE_MIME_LIST = [
  'image/heif',
  'image/heif-sequence',
  'image/heic',
  'image/heic-sequence',
  'image/avif',
  'image/avif-sequence',
  '.heif',
  '.heifs',
  '.heic',
  '.heics',
  '.avif',
  '.avifs',
];
export const calcImageAcceptList = () => {
  // Desktop Safari allows selecting HEIC images with simple image/* wildcard
  // But if we provide a more specific HEIC types - safari starts to convert any images to HEIC
  if (browserInfo.safariDesktop) {
    return [BASIC_IMAGE_WILDCARD];
  }
  // Other browsers allows to select HEIC images with more specific HEIC types only
  // Mobile Safari will allow to select HEIC images even with simple image/* wildcard and it will convert them to JPEG by default (behaviour could be changed in file picker UI)
  // Hope it will be fixed in the future so we'll add specific types so that Mobile Safari will know that we're supporting HEIC images
  return [BASIC_IMAGE_WILDCARD, ...HEIC_IMAGE_MIME_LIST];
};
export const IMAGE_ACCEPT_LIST = calcImageAcceptList();
/**
 * @param {string[]} [fileTypes]
 * @returns {string[]}
 */
export const mergeFileTypes = (fileTypes) => {
  if (!fileTypes) {
    return [];
  }
  return fileTypes
    .filter((item) => typeof item === 'string')
    .map((str) => stringToArray(str))
    .flat();
};
/**
 * @param {String} mimeType
 * @param {String[]} allowedFileTypes
 * @returns {Boolean}
 */
export const matchMimeType = (mimeType, allowedFileTypes) => {
  return allowedFileTypes.some((type) => {
    if (type.endsWith('*')) {
      type = type.replace('*', '');
      return mimeType.startsWith(type);
    }
    return mimeType === type;
  });
};
/**
 * @param {String} fileName
 * @param {String[]} allowedFileTypes
 * @returns {Boolean}
 */
export const matchExtension = (fileName, allowedFileTypes) => {
  return allowedFileTypes.some((type) => {
    if (!type.startsWith('.')) {
      return false;
    }
    return fileName.toLowerCase().endsWith(type.toLowerCase());
  });
};
/**
 * @param {File | Blob} file
 * @returns {Boolean}
 */
export const fileIsImage = (file) => {
  let type = file?.type;
  if (!type) {
    return false;
  }
  return matchMimeType(type, IMAGE_ACCEPT_LIST);
};
/**
 * Checks if the given data is a Blob.
 *
 * @param {unknown} data - The data to check.
 * @returns {boolean} - True if the data is a Blob, false otherwise.
 */
export const isBlob = (data) => {
  return typeof Blob !== 'undefined' && data instanceof Blob;
};
/**
 * Checks if the given data is a File.
 *
 * @param {unknown} data - The data to check.
 * @returns {boolean} - True if the data is a File, false otherwise.
 */
export const isFile = (data) => {
  return typeof File !== 'undefined' && data instanceof File;
};