Skip to content

Commit 52d1519

Browse files
committed
Got TS-based createReducer transform mostly working
1 parent 56bb58b commit 52d1519

File tree

4 files changed

+113
-30
lines changed

4 files changed

+113
-30
lines changed

packages/rtk-codemods2/transforms/createReducerBuilder/__testfixtures__/basic-ts.output.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ createReducer(initialState, (builder) => {
55
});
66

77
createReducer(initialState, (builder) => {
8-
builder.addCase(todoAdded, function(state: SliceState, action: PayloadAction<string>) {
8+
builder.addCase(todoAdded, (state: SliceState, action: PayloadAction<string>) => {
99
// stuff
1010
});
1111
});
Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
11
createReducer(initialState, {
2-
[todoAdded]: (state, action) => {
2+
[todoAdded1a]: (state, action) => {
33
// stuff
44
},
5+
[todoAdded1b]: (state, action) => action.payload,
6+
[todoAdded1c + "test"]: (state, action) => {
7+
// stuff
8+
},
9+
[todoAdded1d](state, action) {
10+
// stuff
11+
},
12+
[todoAdded1e]: function(state, action) {
13+
// stuff
14+
},
15+
todoAdded1f: (state, action) => {
16+
//stuff
17+
}
518
});
619

20+
721
createReducer(initialState, {
8-
[todoAdded](state, action) {
22+
[todoAdded2a]: (state, action) => {
923
// stuff
1024
},
11-
});
25+
[todoAdded2b](state, action) {
26+
// stuff
27+
},
28+
[todoAdded2c]: function(state, action) {
29+
// stuff
30+
}
31+
});
Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,36 @@
11
createReducer(initialState, (builder) => {
2-
builder.addCase(todoAdded, (state, action) => {
2+
builder.addCase(todoAdded1a, (state, action) => {
33
// stuff
44
});
5+
6+
builder.addCase(todoAdded1b, (state, action) => action.payload);
7+
8+
builder.addCase(todoAdded1c + "test", (state, action) => {
9+
// stuff
10+
});
11+
12+
builder.addCase(todoAdded1d, (state, action) => {
13+
// stuff
14+
});
15+
16+
builder.addCase(todoAdded1e, (state, action) => {
17+
// stuff
18+
});
19+
builder.addCase(todoAdded1f, (state, action) => {
20+
//stuff
21+
});
522
});
623

24+
725
createReducer(initialState, (builder) => {
8-
builder.addCase(todoAdded, function(state, action) {
26+
builder.addCase(todoAdded2a, (state, action) => {
927
// stuff
1028
});
11-
});
29+
30+
builder.addCase(todoAdded2b, (state, action) => {
31+
// stuff
32+
});
33+
builder.addCase(todoAdded2c, (state, action) => {
34+
// stuff
35+
});
36+
});
Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,66 @@
11
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'];
416

517
function wrapInAddCaseExpression(
618
j: JSCodeshift,
7-
member: namedTypes.Identifier,
8-
arrowArguments: any[]
19+
key: ObjectKey,
20+
params: PatternKind[],
21+
body: BlockStatement | ExpressionKind
922
) {
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+
])
1329
);
1430
}
1531

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+
}
2662

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));
3164
}
3265

3366
const transform: Transform = (file, api) => {
@@ -42,15 +75,20 @@ const transform: Transform = (file, api) => {
4275
arguments: { 1: { type: 'ObjectExpression' } },
4376
})
4477
.forEach((path) => {
78+
const reducerObjectExpression = path.node.arguments[1] as ObjectExpression;
4579
j(path).replaceWith(
4680
j.callExpression(j.identifier('createReducer'), [
4781
path.node.arguments[0],
48-
reducerPropsToBuilderExpression(j, path.node.arguments[1]),
82+
reducerPropsToBuilderExpression(j, reducerObjectExpression),
4983
])
5084
);
5185
})
52-
.toSource()
86+
.toSource({
87+
arrowParensAlways: true,
88+
})
5389
);
5490
};
5591

92+
export const parser = 'tsx';
93+
5694
export default transform;

0 commit comments

Comments
 (0)