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.

58 lines
1.9 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) ? e.slice(EXTENSION_DELIMITER.length) : e
  29. )
  30. return maybeFileName => {
  31. if ((typeof maybeFileName as unknown) !== 'string') {
  32. throw TypeError('Argument should be a string.')
  33. }
  34. const fileName = maybeFileName as string
  35. const [, ...extensions] = fileName.split(EXTENSION_DELIMITER)
  36. if (config.allowMultipleExtensions) {
  37. return validExtensions.reduce<boolean>(
  38. (isValid, validExtension) => isValid || extensions.includes(validExtension),
  39. false
  40. )
  41. }
  42. return validExtensions.reduce<boolean>(
  43. (isValid, validExtension) => isValid || extensions.join(EXTENSION_DELIMITER).endsWith(validExtension),
  44. false
  45. )
  46. }
  47. }
  48. export default isValidFileName