import { Injectable } from '@angular/core' ; import { ObNotificationService } from '../../notification/notification.service' ; import { ObEMimeTypes , ObEWildCardMimeTypes , ObIFileValidation } from '../file-upload.model' ; import { ObAcceptAllPipe } from './accept-all.pipe' ; @ Injectable ( ) export class ObValidationService { private readonly areAllTypesAllowed = new ObAcceptAllPipe ( ) . transform ; constructor ( private readonly notification ) { } public filterInvalidFiles ( files , accept = [ '*' ] , maxSize , multiple ) { const dispatchedFiles = this . dispatchFiles ( files , accept , maxSize , multiple ) ; this . notifyErrors ( 'i18n.oblique.file-upload.error.single' , { ignoredFiles : dispatchedFiles . overflowing } ) ; this . notifyErrors ( 'i18n.oblique.file-upload.error.type' , { ignoredFiles : dispatchedFiles . invalid , supportedTypes : accept . join ( ', ' ) } ) ; this . notifyErrors ( 'i18n.oblique.file-upload.error.size' , { ignoredFiles : dispatchedFiles . tooLarge , maxSize } ) ; return dispatchedFiles . valid ; } private dispatchFiles ( files , accept , maxSize , multiple ) { return files . reduce ( ( result , file , index ) => { const size = file . size / 1024 / 1024 ; if ( index > 0 && ! multiple ) { result . overflowing . push ( file . name ) ; } else if ( ! this . isFileTypeValid ( file . name . toLowerCase ( ) , accept ) ) { result . invalid . push ( file . name ) ; } else if ( size > maxSize ) { result . tooLarge . push ( `${ file . name } (${ size . toFixed ( 2 ) } MB)` ) ; } else { result . valid . push ( file ) ; } return result ; } , { valid : [ ] , overflowing : [ ] , invalid : [ ] , tooLarge : [ ] } ) ; } private notifyErrors ( message , parameters ) { if ( parameters . ignoredFiles . length ) { const params = { ... parameters , ignoredFiles : parameters . ignoredFiles . join ( ', ' ) } ; this . notification . error ( { message , messageParams : params , title : 'i18n.oblique.file-upload.error.title' } ) ; } } private isFileTypeValid ( filename , accept ) { return this . areAllTypesAllowed ( accept ) || this . hasValidMimeType ( filename , accept ) || this . hasValidExtension ( filename , accept ) ; } private hasValidMimeType ( filename , accept ) { return accept . filter ( type => type . includes ( '/' ) ) . some ( type => this . isMimeTypeValid ( filename , type . trim ( ) ) ) ; } private hasValidExtension ( filename , accept ) { return accept . filter ( type => ! type . includes ( '/' ) ) . some ( type => this . isExtensionValid ( filename , type . trim ( ) ) ) ; } private isMimeTypeValid ( filename , allowedFileType ) { const fileExtension = filename . split ( '.' ) [ 1 ] ; return allowedFileType . endsWith ( '*' ) ? ObEWildCardMimeTypes [ allowedFileType ] ?. includes ( fileExtension ) : ObEMimeTypes [ allowedFileType ] ?. includes ( fileExtension ) ; } private isExtensionValid ( filename , allowedFileType ) { return allowedFileType === `.${ filename . split ( '.' ) . pop ( ) }` ; } }