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.

66 lines
2.0 KiB

  1. const EXTENSION_DELIMITER = '.'
  2. const MULTIPLE_VALID_EXTENSION_DELIMITER = ' '
  3. export type IsValidFilenameConfig = {
  4. validExtensions: string | string[]
  5. allowMultipleExtensions?: boolean
  6. }
  7. type IsValidFileName = (config: IsValidFilenameConfig) => (maybeFileName: string) => boolean
  8. const isValidFileName: IsValidFileName = config => {
  9. let validExtensionsArray: string[]
  10. const maybeValidExtensions = config.validExtensions as unknown
  11. if (typeof maybeValidExtensions === 'string') {
  12. validExtensionsArray = (config.validExtensions as string)
  13. .split(MULTIPLE_VALID_EXTENSION_DELIMITER)
  14. .filter(p => p.trim().length > 0)
  15. } else if (
  16. Array.isArray(maybeValidExtensions)
  17. && (config.validExtensions as unknown[]).every(s => typeof s === 'string')
  18. ) {
  19. if ((config.validExtensions as unknown[]).length < 1) {
  20. throw RangeError('There must be at least 1 valid extension defined.')
  21. }
  22. validExtensionsArray = config.validExtensions as string[]
  23. } else {
  24. throw TypeError('Valid extensions should be a space-delimited string or a string array.')
  25. }
  26. // strip . in valid extensions for easier matching
  27. const validExtensions = validExtensionsArray.map(e => (
  28. e.startsWith(EXTENSION_DELIMITER)
  29. ? e.slice(EXTENSION_DELIMITER.length)
  30. : e
  31. ))
  32. return maybeFileName => {
  33. if (typeof maybeFileName as unknown !== 'string') {
  34. throw TypeError('Argument should be a string.')
  35. }
  36. const fileName = maybeFileName as string
  37. const [, ...extensions] = fileName.split(EXTENSION_DELIMITER)
  38. if (config.allowMultipleExtensions) {
  39. return validExtensions.reduce<boolean>(
  40. (isValid, validExtension) => (
  41. isValid
  42. || extensions.includes(validExtension)
  43. ),
  44. false
  45. )
  46. }
  47. return validExtensions.reduce<boolean>(
  48. (isValid, validExtension) => (
  49. isValid
  50. || extensions.join(EXTENSION_DELIMITER).endsWith(validExtension)
  51. ),
  52. false
  53. )
  54. }
  55. }
  56. export default isValidFileName