import { API , FileInfo , Options , ImportSpecifier , MemberExpression , TSTypeReference , ImportDeclaration , } from 'jscodeshift' ; import { getImportRenameMap } from './getImportRenameMap' ; const importsToRemove = [ 'ButtonVariant' , 'ButtonIconPosition' , 'ButtonSize' , 'ButtonIconSize' , 'OutlineButtonVariant' , 'DropdownButtonVariant' , 'IconButtonVariant' , 'TextButtonVariant' , 'DeprecatedButtonVariant' , 'ButtonIconPosition' , ] ; const enumsToMap = { 'ButtonVariant.Primary' : 'primary' , 'ButtonVariant.Secondary' : 'secondary' , 'Button.Variant.Primary' : 'primary' , 'Button.Variant.Secondary' : 'secondary' , 'OutlineButtonVariant.Primary' : 'primary' , 'OutlineButtonVariant.Secondary' : 'secondary' , 'OutlineButtonVariant.Inverse' : 'inverse' , 'OutlineButton.Variant.Primary' : 'primary' , 'OutlineButton.Variant.Secondary' : 'secondary' , 'OutlineButton.Variant.Inverse' : 'inverse' , 'DropdownButtonVariant.Primary' : 'primary' , 'DropdownButtonVariant.Secondary' : 'secondary' , 'DropdownButton.Variant.Primary' : 'primary' , 'DropdownButton.Variant.Secondary' : 'secondary' , 'IconButtonVariant.Square' : 'square' , 'IconButtonVariant.SquareFilled' : 'squareFilled' , 'IconButtonVariant.Plain' : 'plain' , 'IconButtonVariant.Circle' : 'circle' , 'IconButtonVariant.CircleFilled' : 'circleFilled' , 'IconButtonVariant.Inverse' : 'inverse' , 'IconButtonVariant.InverseFilled' : 'inverseFilled' , 'IconButton.Variant.Square' : 'square' , 'IconButton.Variant.SquareFilled' : 'squareFilled' , 'IconButton.Variant.Plain' : 'plain' , 'IconButton.Variant.Circle' : 'circle' , 'IconButton.Variant.CircleFilled' : 'circleFilled' , 'IconButton.Variant.Inverse' : 'inverse' , 'IconButton.Variant.InverseFilled' : 'inverseFilled' , 'TextButtonVariant.Default' : 'text' , 'TextButtonVariant.Inverse' : 'inverse' , 'TextButton.Variant.Default' : 'text' , 'TextButton.Variant.Inverse' : 'inverse' , 'Hyperlink.Variant.Default' : 'text' , 'Hyperlink.Variant.Inverse' : 'inverse' , 'DeprecatedButtonVariant.Primary' : 'primary' , 'DeprecatedButtonVariant.Secondary' : 'secondary' , 'DeprecatedButtonVariant.Delete' : 'delete' , 'deprecated_Button.Variant.Primary' : 'primary' , 'deprecated_Button.Variant.Secondary' : 'secondary' , 'deprecated_Button.Variant.Delete' : 'delete' , 'ButtonIconPosition.Left' : 'left' , 'ButtonIconPosition.Right' : 'right' , 'TextButton.IconPosition.Left' : 'left' , 'TextButton.IconPosition.Right' : 'right' , 'ButtonSize.Small' : 'small' , 'ButtonSize.Medium' : 'medium' , 'ButtonSize.Large' : 'large' , 'Button.Size.Small' : 'small' , 'Button.Size.Medium' : 'medium' , 'Button.Size.Large' : 'large' , 'IconButton.Size.Small' : 'small' , 'IconButton.Size.Medium' : 'medium' , 'IconButton.Size.Large' : 'large' , 'DeleteButton.Size.Small' : 'small' , 'DeleteButton.Size.Medium' : 'medium' , 'DeleteButton.Size.Large' : 'large' , 'OutlineButton.Size.Small' : 'small' , 'OutlineButton.Size.Medium' : 'medium' , 'OutlineButton.Size.Large' : 'large' , 'TextButton.Size.Small' : 'small' , 'TextButton.Size.Medium' : 'medium' , 'HighlightButton.Size.Small' : 'small' , 'HighlightButton.Size.Medium' : 'medium' , 'HighlightButton.Size.Large' : 'large' , 'DropdownButton.Size.Medium' : 'medium' , 'DropdownButton.Size.Large' : 'large' , 'deprecated_Button.Size.Small' : 'small' , 'deprecated_Button.Size.Medium' : 'medium' , 'deprecated_Button.Size.Large' : 'large' , } ; const enumToLiteralUnionMap = { ButtonVariant : [ 'primary' , 'secondary' ] , ButtonIconPosition : [ 'left' , 'right' ] , ButtonIconSize : [ 'small' , 'medium' , 'large' ] , OutlineButtonVariant : [ 'primary' , 'secondary' , 'inverse' ] , DropdownButtonVariant : [ 'primary' , 'secondary' ] , IconButtonVariant : [ 'square' , 'squareFilled' , 'plain' , 'circle' , 'circleFilled' , 'inverse' , 'inverseFilled' , ] , TextButtonVariant : [ 'text' , 'inverse' ] , DeprecatedButtonVariant : [ 'primary' , 'secondary' , 'delete' ] , } ; export default function transformer ( file , api , options ) { const j = api . jscodeshift ; const root = j ( file . source ) ; const { containsCanvasImports , importMap } = getImportRenameMap ( j , root , '@workday/canvas-kit-react/button' ) ; if ( ! containsCanvasImports ) { return file . source ; } root . find ( j . ImportSpecifier , ( node ) => { return importsToRemove . includes ( node . imported . name ) ; } ) . remove ( ) ; const reverseImportMap = Object . keys ( importMap ) . reduce ( ( result , key ) => { result [ importMap [ key ] ] = key ; return result ; } , { } as Record < string , string > ) ; function findEnumReplacement ( node , candidates = enumsToMap , matched = '' ) { let candidate ; for ( candidate in candidates ) { if ( node . object . type === 'Identifier' && node . property . type === 'Identifier' && `${ reverseImportMap [ node . object . name ] }.${ node . property . name }${ matched }` === candidate ) { return enumsToMap [ candidate ] ; } const parts = candidate . split ( '.' ) ; const last = parts . splice ( - 1 , 1 ) . join ( '' ) ; if ( node . property . type === 'Identifier' && node . property . name === last && node . object . type === 'MemberExpression' ) { return findEnumReplacement ( node . object , enumsToMap , `.${ last }` ) ; } } return null ; } root . find ( j . MemberExpression , ( node ) => { const matched = findEnumReplacement ( node ) ; return matched !== null ; } ) . replaceWith ( nodePath => { const matched = findEnumReplacement ( nodePath . value ) ; return j . literal ( matched ) ; } ) ; root . find ( j . ImportSpecifier , { imported : { name : 'beta_Button' } } ) . forEach ( nodePath => { const parent = nodePath . parent . value as ImportDeclaration ; if ( parent . source && typeof parent . source . value === 'string' && parent . source . value . includes ( '@workday/canvas-kit-react' ) ) { nodePath . value . imported = j . identifier ( 'Button' ) ; if ( nodePath . value . local ?. name === 'Button' ) { nodePath . value . local = null ; } } return nodePath ; } ) ; example function findTypeRename ( node ) { if ( node . type === 'TSTypeReference' && node . typeName . type === 'Identifier' ) { let identifier ; for ( identifier in enumToLiteralUnionMap ) { if ( node . typeName . name === importMap [ identifier ] ) { return enumToLiteralUnionMap [ identifier ] ; } } } return null ; } root . find ( j . TSTypeReference , ( node ) => ! ! findTypeRename ( node ) ) . replaceWith ( nodePath => { const node = nodePath . value ; const matches = findTypeRename ( node ) ; if ( matches ) { return j . tsUnionType ( matches . map ( literal => j . tsLiteralType ( { type : 'StringLiteral' , value : literal } ) ) ) ; } return nodePath . value ; } ) ; return root . toSource ( ) ; }