import { ImportSpecifier , ImportDefaultSpecifier , ImportNamespaceSpecifier , Collection , API , } from 'jscodeshift' ; export type ImportSpecifierArray = ( ImportSpecifier | ImportNamespaceSpecifier | ImportDefaultSpecifier ) [ ] ; example export function filterImportSpecifiers ( importSpecifiers , importNames ? ) { const filteredSpecifiers = [ ] as ImportSpecifier [ ] ; importSpecifiers . forEach ( specifier => { if ( specifier . type === 'ImportSpecifier' ) { if ( importNames && importNames . includes ( specifier . imported . name ) ) { filteredSpecifiers . push ( specifier ) ; } else { filteredSpecifiers . push ( specifier ) ; } } } ) ; return filteredSpecifiers ; } export type RenameMap = { [ key ] : string ; } ; example export function renameImportSpecifiers ( importSpecifiers , renameMap ) { importSpecifiers . forEach ( specifier => { const specifierName = specifier . imported . name ; if ( specifierName in renameMap ) { specifier . imported . name = renameMap [ specifierName ] ; } } ) ; return importSpecifiers ; } example export function filterImportDefaultSpecifiers ( importSpecifiers , importNames ? ) { const filteredSpecifiers = [ ] as ImportDefaultSpecifier [ ] ; importSpecifiers . forEach ( specifier => { if ( specifier . type === 'ImportDefaultSpecifier' ) { const localName = specifier . local ?. name || '' ; if ( importNames && importNames . includes ( localName ) ) { filteredSpecifiers . push ( specifier ) ; } else { filteredSpecifiers . push ( specifier ) ; } } } ) ; return filteredSpecifiers ; } example export function renameImportDefaultSpecifiers ( importSpecifiers , renameMap ) { importSpecifiers . forEach ( specifier => { const specifierName = specifier . local ?. name ; if ( specifier . local && specifierName && specifierName in renameMap ) { specifier . local . name = renameMap [ specifierName ] ; } } ) ; return importSpecifiers ; } example export function hasImportSpecifiers ( api , root , packageName , specifiers ) { const j = api . jscodeshift ; return ! ! root . find ( j . ImportDeclaration , nodePath => { const value = nodePath . source . value ; if ( typeof packageName === 'string' ? value === packageName : packageName . includes ( value as string ) ) { return true ; } const mainPackage = ( typeof packageName === 'string' ? [ packageName ] : packageName ) . map ( s => s . split ( '/' ) . slice ( 0 , - 1 ) . join ( '/' ) ) ; if ( mainPackage . includes ( value as string ) ) { return ! ! ( nodePath . specifiers || [ ] ) . find ( specifier => { if ( specifier . type === 'ImportSpecifier' ) { const specifierName = specifier . imported . name ; return specifiers . includes ( specifierName ) ; } return false ; } ) ; } return false ; } ) ; } export function renameImports ( api , root , packageName , specifierMap ) { const j = api . jscodeshift ; if ( ! hasImportSpecifiers ( api , root , packageName , Object . keys ( specifierMap ) ) ) { return root ; } const mainPackage = packageName . split ( '/' ) . slice ( 0 , - 1 ) . join ( '/' ) ; root . find ( j . ImportDeclaration , { source : { value : mainPackage } } ) . forEach ( nodePath => { nodePath . value . specifiers ?. forEach ( specifier => { if ( specifier . type === 'ImportSpecifier' ) { if ( Object . keys ( specifierMap ) . includes ( specifier . imported . name ) ) { specifier . imported . name = specifierMap [ specifier . imported . name ] ; } } } ) ; } ) ; root . find ( j . ImportDeclaration , { source : { value : packageName } } ) . forEach ( nodePath => { nodePath . value . specifiers ?. forEach ( specifier => { if ( specifier . type === 'ImportDefaultSpecifier' ) { if ( specifier . local && Object . keys ( specifierMap ) . includes ( specifier . local . name ) ) { specifier . local . name = specifierMap [ specifier . local . name ] ; } } if ( specifier . type === 'ImportSpecifier' ) { if ( Object . keys ( specifierMap ) . includes ( specifier . imported . name ) ) { specifier . imported . name = specifierMap [ specifier . imported . name ] ; } } } ) ; } ) ; root . find ( j . TSTypeReference , { typeName : { type : 'Identifier' } } ) . forEach ( nodePath => { if ( nodePath . value . typeName . type === 'Identifier' && Object . keys ( specifierMap ) . includes ( nodePath . value . typeName . name ) ) { nodePath . value . typeName . name = specifierMap [ nodePath . value . typeName . name ] ; } } ) ; root . find ( j . TSInterfaceDeclaration ) . forEach ( nodePath => { nodePath . node . extends ?. forEach ( typeExtension => { if ( typeExtension . expression . type === 'Identifier' && Object . keys ( specifierMap ) . includes ( typeExtension . expression . name ) ) { typeExtension . expression . name = specifierMap [ typeExtension . expression . name ] ; } } ) ; } ) ; root . find ( j . JSXIdentifier ) . forEach ( nodePath => { if ( Object . keys ( specifierMap ) . includes ( nodePath . value . name ) ) { nodePath . node . name = specifierMap [ nodePath . value . name ] ; } } ) ; root . find ( j . MemberExpression , { object : { type : 'Identifier' } } ) . forEach ( nodePath => { if ( nodePath . value . object . type === 'Identifier' && Object . keys ( specifierMap ) . includes ( nodePath . value . object . name ) ) { nodePath . value . object . name = specifierMap [ nodePath . value . object . name ] ; } } ) ; return root ; }