Useful methods for file-related functions.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
1.9 KiB

  1. const MULTIPLE_VALID_MIME_TYPE_DELIMITER = ' '
  2. const CATCH_ALL_MIME_TYPES = ['*', '*/*']
  3. const MIME_TYPE_FORMAT_DELIMITER = '/'
  4. // catch-all for format, e.g. "image/*" matches all MIME types starting with "image/"
  5. const MIME_TYPE_FORMAT_CATCH_ALL = '*'
  6. export type IsValidMimeTypeConfig = {
  7. validMimeTypes: string | string[]
  8. }
  9. type IsValidMimeType = (config: IsValidMimeTypeConfig) => (mimeType: string) => boolean
  10. const isValidMimeType: IsValidMimeType = config => {
  11. let validMimeTypes: string[]
  12. const maybeValidMimeTypes = config.validMimeTypes as unknown
  13. if (typeof maybeValidMimeTypes === 'string') {
  14. validMimeTypes = (config.validMimeTypes as string)
  15. .split(MULTIPLE_VALID_MIME_TYPE_DELIMITER)
  16. .filter(p => p.trim().length > 0)
  17. } else if (
  18. Array.isArray(maybeValidMimeTypes) &&
  19. (config.validMimeTypes as unknown[]).every(s => typeof s === 'string')
  20. ) {
  21. if ((config.validMimeTypes as unknown[]).length < 1) {
  22. throw RangeError('There must be at least 1 valid extension defined.')
  23. }
  24. validMimeTypes = config.validMimeTypes as string[]
  25. } else {
  26. throw TypeError('Valid MimeTypes should be a space-delimited string or a string array.')
  27. }
  28. return mimeType => {
  29. if ((typeof mimeType as unknown) !== 'string') {
  30. throw TypeError('Argument should be a string.')
  31. }
  32. // short-circuit valid MIME types that are catch-all
  33. if (validMimeTypes.some(a => CATCH_ALL_MIME_TYPES.includes(a))) {
  34. return true
  35. }
  36. return validMimeTypes.reduce<boolean>((isValid, validMimeType) => {
  37. const [type, format] = validMimeType.split(MIME_TYPE_FORMAT_DELIMITER)
  38. // maybe short circuit matching format catch-all valid MIME types?
  39. if (format === MIME_TYPE_FORMAT_CATCH_ALL) {
  40. return isValid || mimeType.startsWith(type + MIME_TYPE_FORMAT_DELIMITER)
  41. }
  42. return isValid || mimeType === validMimeType
  43. }, false)
  44. }
  45. }
  46. export default isValidMimeType