Skip to content

Commit 7f1e99c

Browse files
committed
✨ CLI now supports configs using cjs export schemes
1 parent e9b263e commit 7f1e99c

File tree

4 files changed

+84
-56
lines changed

4 files changed

+84
-56
lines changed

.changeset/great-frogs-refuse.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@codeshift/cli': minor
3+
---
4+
5+
CLI now supports configs exported with cjs and es module types

packages/cli/src/main.spec.ts

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,14 @@ describe('main', () => {
1515
(PluginManager as jest.Mock).mockReturnValue({
1616
install: () => Promise.resolve(undefined),
1717
require: (codemodName: string) => ({
18-
default: {
19-
transforms: {
20-
'18.0.0': `${codemodName}/path/to/18.js`,
21-
'19.0.0': `${codemodName}/path/to/19.js`,
22-
'20.0.0': `${codemodName}/path/to/20.js`,
23-
},
24-
presets: {
25-
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
26-
'update-imports': `${codemodName}/path/to/update-imports.js`,
27-
},
18+
transforms: {
19+
'18.0.0': `${codemodName}/path/to/18.js`,
20+
'19.0.0': `${codemodName}/path/to/19.js`,
21+
'20.0.0': `${codemodName}/path/to/20.js`,
22+
},
23+
presets: {
24+
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
25+
'update-imports': `${codemodName}/path/to/update-imports.js`,
2826
},
2927
}),
3028
uninstallAll: () => Promise.resolve(),
@@ -333,10 +331,8 @@ describe('main', () => {
333331
(PluginManager as jest.Mock).mockReturnValue({
334332
install: () => Promise.resolve(undefined),
335333
require: (codemodName: string) => ({
336-
default: {
337-
presets: {
338-
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
339-
},
334+
presets: {
335+
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
340336
},
341337
}),
342338
uninstallAll: () => Promise.resolve(),
@@ -360,10 +356,8 @@ describe('main', () => {
360356
install: () => Promise.resolve(undefined),
361357
// @ts-ignore
362358
require: (codemodName: string) => ({
363-
default: {
364-
presets: {
365-
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
366-
},
359+
presets: {
360+
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
367361
},
368362
}),
369363
uninstallAll: () => Promise.resolve(),
@@ -472,10 +466,8 @@ describe('main', () => {
472466
install: () => Promise.resolve(undefined),
473467
// @ts-ignore
474468
require: (codemodName: string) => ({
475-
default: {
476-
transforms: {
477-
'20.0.0': `${codemodName}/path/to/20.js`,
478-
},
469+
transforms: {
470+
'20.0.0': `${codemodName}/path/to/20.js`,
479471
},
480472
}),
481473
uninstallAll: () => Promise.resolve(),
@@ -499,10 +491,8 @@ describe('main', () => {
499491
install: () => Promise.resolve(undefined),
500492
// @ts-ignore
501493
require: (codemodName: string) => ({
502-
default: {
503-
transforms: {
504-
'20.0.0': `${codemodName}/path/to/20.js`,
505-
},
494+
transforms: {
495+
'20.0.0': `${codemodName}/path/to/20.js`,
506496
},
507497
}),
508498
uninstallAll: () => Promise.resolve(),
@@ -517,4 +507,37 @@ describe('main', () => {
517507
).resolves.not.toThrow();
518508
});
519509
});
510+
511+
describe('when reading configs using non-cjs exports', () => {
512+
it('should read configs exported with export default', async () => {
513+
(PluginManager as jest.Mock).mockReturnValue({
514+
install: () => Promise.resolve(undefined),
515+
// @ts-ignore
516+
require: (codemodName: string) => ({
517+
default: {
518+
transforms: {
519+
'18.0.0': `${codemodName}/path/to/18.js`,
520+
},
521+
},
522+
}),
523+
uninstallAll: () => Promise.resolve(),
524+
});
525+
526+
await main([mockPath], {
527+
packages: 'mylib@18.0.0',
528+
parser: 'babel',
529+
extensions: 'js',
530+
});
531+
532+
expect(jscodeshift.run).toHaveBeenCalledTimes(1);
533+
expect(jscodeshift.run).toHaveBeenCalledWith(
534+
'@codeshift/mod-mylib/path/to/18.js',
535+
expect.arrayContaining([mockPath]),
536+
expect.objectContaining({
537+
parser: 'babel',
538+
extensions: 'js',
539+
}),
540+
);
541+
});
542+
});
520543
});

packages/cli/src/main.ts

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,19 @@ export default async function main(paths: string[], flags: Flags) {
3636
.split(/[@#]/)
3737
.filter(str => !!str)[0]
3838
.replace('/', '__');
39-
const codemodName = `@codeshift/mod-${pkgName}`;
39+
const packageName = `@codeshift/mod-${pkgName}`;
4040

41-
await packageManager.install(codemodName);
42-
// TODO: check if default exists first. module.exports might not have it
43-
const { default: codeshiftConfig } = packageManager.require(codemodName);
41+
await packageManager.install(packageName);
42+
const codeshiftPackage = packageManager.require(packageName);
4443

45-
const codemodIds = pkg.split(/(?=[@#])/).filter(str => !!str);
46-
codemodIds.shift();
44+
const config = codeshiftPackage.default
45+
? codeshiftPackage.default
46+
: codeshiftPackage;
4747

48-
const transformIds = codemodIds
48+
const rawTransformIds = pkg.split(/(?=[@#])/).filter(str => !!str);
49+
rawTransformIds.shift();
50+
51+
const transformIds = rawTransformIds
4952
.filter(id => id.startsWith('@'))
5053
.map(id => id.substring(1))
5154
.sort((idA, idB) => {
@@ -54,7 +57,7 @@ export default async function main(paths: string[], flags: Flags) {
5457
return 0;
5558
});
5659

57-
const presetIds = codemodIds
60+
const presetIds = rawTransformIds
5861
.filter(id => id.startsWith('#'))
5962
.map(id => id.substring(1));
6063

@@ -66,47 +69,47 @@ export default async function main(paths: string[], flags: Flags) {
6669
);
6770
}
6871

69-
if (!codeshiftConfig.transforms || !codeshiftConfig.transforms[id]) {
72+
if (!config.transforms || !config.transforms[id]) {
7073
throw new InvalidUserInputError(
7174
`Invalid version provided to the --packages flag. Unable to resolve version "${id}" for package "${pkgName}"`,
7275
);
7376
}
7477
});
7578

7679
presetIds.forEach(id => {
77-
if (!codeshiftConfig.presets || !codeshiftConfig.presets[id]) {
80+
if (!config.presets || !config.presets[id]) {
7881
throw new InvalidUserInputError(
7982
`Invalid preset provided to the --packages flag. Unable to resolve preset "${id}" for package "${pkgName}"`,
8083
);
8184
}
8285
});
8386

8487
// Get transform file paths
85-
if (codeshiftConfig.transforms) {
88+
if (config.transforms) {
8689
if (flags.sequence) {
87-
Object.entries(codeshiftConfig.transforms as Record<string, string>)
90+
Object.entries(config.transforms as Record<string, string>)
8891
.filter(([key]) => semver.satisfies(key, `>=${transformIds[0]}`))
8992
.forEach(([, path]) => transforms.push(path));
9093
} else {
91-
Object.entries(
92-
codeshiftConfig.transforms as Record<string, string>,
93-
).forEach(([id, path]) => {
94-
if (transformIds.includes(id)) {
95-
transforms.push(path);
96-
}
97-
});
94+
Object.entries(config.transforms as Record<string, string>).forEach(
95+
([id, path]) => {
96+
if (transformIds.includes(id)) {
97+
transforms.push(path);
98+
}
99+
},
100+
);
98101
}
99102
}
100103

101104
// Get preset file paths
102-
if (codeshiftConfig.presets) {
103-
Object.entries(
104-
codeshiftConfig.presets as Record<string, string>,
105-
).forEach(([id, path]) => {
106-
if (presetIds.includes(id)) {
107-
transforms.push(path);
108-
}
109-
});
105+
if (config.presets) {
106+
Object.entries(config.presets as Record<string, string>).forEach(
107+
([id, path]) => {
108+
if (presetIds.includes(id)) {
109+
transforms.push(path);
110+
}
111+
},
112+
);
110113
}
111114
}
112115
}

packages/cli/src/types.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ export type Transform = (
66
options: Options,
77
) => string;
88

9-
export class ValidationError extends Error {}
10-
export class NoTransformsExistError extends Error {}
11-
129
export interface Flags {
1310
/**
1411
* The transform to run

0 commit comments

Comments
 (0)