1
1
import { namedTypes } from 'ast-types' ;
2
- import { ExpressionKind } from 'ast-types/gen/kinds' ;
3
- import { JSCodeshift , Transform } from 'jscodeshift' ;
2
+ import { ExpressionKind , PatternKind } from 'ast-types/gen/kinds' ;
3
+ import {
4
+ BlockStatement ,
5
+ CallExpression ,
6
+ Expression ,
7
+ ExpressionStatement ,
8
+ JSCodeshift ,
9
+ ObjectExpression ,
10
+ ObjectMethod ,
11
+ ObjectProperty ,
12
+ Transform ,
13
+ } from 'jscodeshift' ;
14
+
15
+ type ObjectKey = ObjectMethod [ 'key' ] & ObjectProperty [ 'key' ] ;
4
16
5
17
function wrapInAddCaseExpression (
6
18
j : JSCodeshift ,
7
- member : namedTypes . Identifier ,
8
- arrowArguments : any [ ]
19
+ key : ObjectKey ,
20
+ params : PatternKind [ ] ,
21
+ body : BlockStatement | ExpressionKind
9
22
) {
10
- return j . callExpression (
11
- j . memberExpression ( member , j . identifier ( 'addCase' ) , false ) ,
12
- arrowArguments
23
+ const identifier = j . identifier ( 'builder' ) ;
24
+ return j . expressionStatement (
25
+ j . callExpression ( j . memberExpression ( identifier , j . identifier ( 'addCase' ) , false ) , [
26
+ key ,
27
+ j . arrowFunctionExpression ( params , body ) ,
28
+ ] )
13
29
) ;
14
30
}
15
31
16
- export function reducerPropsToBuilderExpression (
17
- j : JSCodeshift ,
18
- defNode : namedTypes . SpreadElement | ExpressionKind
19
- ) {
20
- // @ts -ignore
21
- const [ firstCase , ...restOfCases ] = defNode . properties ;
22
-
23
- const expressionStatement = restOfCases . reduce ( ( acc : any , c : any ) => {
24
- return wrapInAddCaseExpression ( j , acc , [ c . key , c . value ] ) ;
25
- } , wrapInAddCaseExpression ( j , j . identifier ( 'builder' ) , [ firstCase . key , firstCase . value ] ) ) ;
32
+ export function reducerPropsToBuilderExpression ( j : JSCodeshift , defNode : ObjectExpression ) {
33
+ const caseExpressions : ExpressionStatement [ ] = [ ] ;
34
+ for ( let property of defNode . properties ) {
35
+ let key : ObjectKey = null as any ;
36
+ let params : PatternKind [ ] = [ ] ;
37
+ let body : BlockStatement | ExpressionKind = null as any ;
38
+ switch ( property . type ) {
39
+ case 'ObjectMethod' : {
40
+ key = property . key ;
41
+ params = property . params ;
42
+ body = property . body ;
43
+ break ;
44
+ }
45
+ case 'ObjectProperty' : {
46
+ switch ( property . value . type ) {
47
+ case 'ArrowFunctionExpression' :
48
+ case 'FunctionExpression' : {
49
+ key = property . key ;
50
+ params = property . value . params ;
51
+ body = property . value . body ;
52
+ break ;
53
+ }
54
+ }
55
+ }
56
+ }
57
+ if ( ! body ) {
58
+ continue ;
59
+ }
60
+ caseExpressions . push ( wrapInAddCaseExpression ( j , key , params , body ) ) ;
61
+ }
26
62
27
- return j . arrowFunctionExpression (
28
- [ j . identifier ( 'builder' ) ] ,
29
- j . blockStatement ( [ j . expressionStatement ( expressionStatement ) ] )
30
- ) ;
63
+ return j . arrowFunctionExpression ( [ j . identifier ( 'builder' ) ] , j . blockStatement ( caseExpressions ) ) ;
31
64
}
32
65
33
66
const transform : Transform = ( file , api ) => {
@@ -42,15 +75,20 @@ const transform: Transform = (file, api) => {
42
75
arguments : { 1 : { type : 'ObjectExpression' } } ,
43
76
} )
44
77
. forEach ( ( path ) => {
78
+ const reducerObjectExpression = path . node . arguments [ 1 ] as ObjectExpression ;
45
79
j ( path ) . replaceWith (
46
80
j . callExpression ( j . identifier ( 'createReducer' ) , [
47
81
path . node . arguments [ 0 ] ,
48
- reducerPropsToBuilderExpression ( j , path . node . arguments [ 1 ] ) ,
82
+ reducerPropsToBuilderExpression ( j , reducerObjectExpression ) ,
49
83
] )
50
84
) ;
51
85
} )
52
- . toSource ( )
86
+ . toSource ( {
87
+ arrowParensAlways : true ,
88
+ } )
53
89
) ;
54
90
} ;
55
91
92
+ export const parser = 'tsx' ;
93
+
56
94
export default transform ;
0 commit comments