import { enumHas } from './utils' ; export default class ModulesOrder { private groupIndex : number = 0 ; private readonly importGroups : Array < ImportGroup > ; constructor ( optionsItems ) { const hasLib = optionsItems . some ( _ => _ === ModuleType . Lib ) ; const hasUser = optionsItems . some ( _ => _ === ModuleType . User ) ; if ( ! hasLib ) { optionsItems = [ ModuleType . Lib , ... optionsItems ] ; } if ( ! hasUser ) { optionsItems = [ ... optionsItems , ModuleType . User ] ; } this . importGroups = optionsItems . map ( ( _ , i ) => new ImportGroup ( _ , i ) ) ; } check ( path ) { let index = this . importGroups . slice ( this . groupIndex ) . findIndex ( item => item . type === ModuleType . CustomRule && item . check ( path ) ) ; if ( index === - 1 ) { index = this . importGroups . slice ( this . groupIndex ) . findIndex ( item => item . type !== ModuleType . CustomRule && item . check ( path ) ) ; } if ( index === - 1 ) { return false ; } this . groupIndex += index ; return true ; } findImportGroup ( path ) { return this . findImportGroupIndexWith ( index => this . importGroups [ index ] , path ) ; } getCurrentImportGroup ( ) { return this . importGroups [ this . groupIndex ] ; } private findImportGroupIndexWith < T > ( customizer , path ) { const customIndex = this . importGroups . findIndex ( item => item . type === ModuleType . CustomRule && item . check ( path ) ) ; if ( customIndex > - 1 ) { return customizer ( customIndex ) ; } return customizer ( this . importGroups . findIndex ( item => item . check ( path ) ) ) ; } } export enum ModuleType { Lib = 'lib' , User = 'user' , CustomRule = 'custom-rule' } export class ImportGroup { readonly type : ModuleType ; private readonly customRule ? : RegExp ; constructor ( optionsItem , readonly index ) { if ( enumHas ( ModuleType , optionsItem ) ) { this . type = optionsItem as any ; } else { this . type = ModuleType . CustomRule ; this . customRule = new RegExp ( optionsItem ) ; } } check ( path ) { if ( this . type === ModuleType . CustomRule ) { return this . customRule . test ( path ) ; } const isUserModule = path . startsWith ( '/' ) || path . startsWith ( '.' ) ; if ( this . type === ModuleType . User && isUserModule ) { return true ; } if ( this . type === ModuleType . Lib && ! isUserModule ) { return true ; } return false ; } getTitle ( ) { switch ( this . type ) { case ModuleType . Lib : return 'Lib import' ; case ModuleType . User : return 'User import' ; case ModuleType . CustomRule : return `Custom import ${ this . customRule . toString ( ) }` ; } } }