Skip to content

Commit ea2df98

Browse files
authored
Fix Storyblok init codemod (#128)
1 parent 5390090 commit ea2df98

File tree

2 files changed

+119
-22
lines changed

2 files changed

+119
-22
lines changed

src/application/project/code/transformation/javascript/storyblokInitCodemod.ts

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,33 +45,34 @@ export class StoryblokInitCodemod implements Codemod<t.File, StoryblokInitCodemo
4545
CallExpression: path => {
4646
const {callee} = path.node;
4747

48-
// Match direct function calls: targetFunction(...)
49-
if (t.isIdentifier(callee) && callee.name === 'storyblokInit') {
50-
path.node.arguments = [
51-
t.callExpression(
52-
t.identifier(wrapperName),
53-
path.node.arguments,
54-
),
55-
];
56-
57-
modified = true;
48+
const isDirectCall = t.isIdentifier(callee) && callee.name === 'storyblokInit';
49+
const isMemberCall = t.isMemberExpression(callee)
50+
&& t.isIdentifier(callee.property)
51+
&& callee.property.name === 'storyblokInit';
52+
53+
if (!isDirectCall && !isMemberCall) {
54+
return;
5855
}
5956

60-
// Match member expression calls: obj.targetFunction(...)
57+
const args = path.node.arguments;
58+
6159
if (
62-
t.isMemberExpression(callee)
63-
&& t.isIdentifier(callee.property)
64-
&& callee.property.name === 'storyblokInit'
60+
args.length === 1
61+
&& t.isCallExpression(args[0])
62+
&& t.isIdentifier(args[0].callee)
63+
&& args[0].callee.name === wrapperName
6564
) {
66-
path.node.arguments = [
67-
t.callExpression(
68-
t.identifier(wrapperName),
69-
path.node.arguments,
70-
),
71-
];
72-
73-
modified = true;
65+
return;
7466
}
67+
68+
path.node.arguments = [
69+
t.callExpression(
70+
t.identifier(wrapperName),
71+
args,
72+
),
73+
];
74+
75+
modified = true;
7576
},
7677
});
7778

test/application/project/code/transformation/javascript/storyblokInitCodemod.test.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,102 @@ describe('StoryblokInitCodemod', () => {
199199
].join('\n'));
200200
});
201201

202+
it('should not wrap arguments that are already wrapped', async () => {
203+
const transformer = createTransformer();
204+
205+
const input = [
206+
"import { withCroct } from '@croct/storyblok';",
207+
"import { storyblokInit } from '@storyblok/js';",
208+
'',
209+
'storyblokInit(withCroct({ accessToken: "token" }));',
210+
].join('\n');
211+
212+
const {result, modified} = await transformer.apply(input, {
213+
name: 'withCroct',
214+
module: '@croct/storyblok',
215+
});
216+
217+
expect(modified).toBe(false);
218+
expect(result).toBe(input);
219+
});
220+
221+
it('should not wrap member expression arguments that are already wrapped', async () => {
222+
const transformer = createTransformer();
223+
224+
const input = [
225+
"import { withCroct } from '@croct/storyblok';",
226+
"import * as sb from '@storyblok/js';",
227+
'',
228+
'sb.storyblokInit(withCroct({ accessToken: "token" }));',
229+
].join('\n');
230+
231+
const {result, modified} = await transformer.apply(input, {
232+
name: 'withCroct',
233+
module: '@croct/storyblok',
234+
});
235+
236+
expect(modified).toBe(false);
237+
expect(result).toBe(input);
238+
});
239+
240+
it('should not wrap arguments that are already wrapped with an alias', async () => {
241+
const transformer = createTransformer();
242+
243+
const input = [
244+
"import { withCroct as croctWrapper } from '@croct/storyblok';",
245+
"import { storyblokInit } from '@storyblok/js';",
246+
'',
247+
'storyblokInit(croctWrapper({ accessToken: "token" }));',
248+
].join('\n');
249+
250+
const {result, modified} = await transformer.apply(input, {
251+
name: 'withCroct',
252+
module: '@croct/storyblok',
253+
});
254+
255+
expect(modified).toBe(false);
256+
expect(result).toBe(input);
257+
});
258+
259+
it('should not wrap arguments that are already wrapped with no arguments', async () => {
260+
const transformer = createTransformer();
261+
262+
const input = [
263+
"import { withCroct } from '@croct/storyblok';",
264+
"import { storyblokInit } from '@storyblok/js';",
265+
'',
266+
'storyblokInit(withCroct());',
267+
].join('\n');
268+
269+
const {result, modified} = await transformer.apply(input, {
270+
name: 'withCroct',
271+
module: '@croct/storyblok',
272+
});
273+
274+
expect(modified).toBe(false);
275+
expect(result).toBe(input);
276+
});
277+
278+
it('should wrap when the argument is a call to a different function', async () => {
279+
const transformer = createTransformer();
280+
281+
const input = [
282+
"import { storyblokInit } from '@storyblok/js';",
283+
'',
284+
'storyblokInit(otherWrapper({ accessToken: "token" }));',
285+
].join('\n');
286+
287+
const {result, modified} = await transformer.apply(input, {
288+
name: 'withCroct',
289+
module: '@croct/storyblok',
290+
});
291+
292+
expect(modified).toBe(true);
293+
expect(result).toContain(
294+
'storyblokInit(withCroct(otherWrapper({ accessToken: "token" })));',
295+
);
296+
});
297+
202298
it('should add empty statement before import when first statement is not an import', async () => {
203299
const transformer = createTransformer();
204300

0 commit comments

Comments
 (0)