Skip to content

Commit 2aaba32

Browse files
committed
javascript codemod package
1 parent dfc141c commit 2aaba32

File tree

21 files changed

+692
-0
lines changed

21 files changed

+692
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
maintainers: [],
3+
targets: [],
4+
description: 'Codemods for javascript',
5+
transforms: {},
6+
presets: {
7+
'import-from-root': require.resolve('./import-from-root/transform'),
8+
'remove-debugger': require.resolve('./remove-debugger/transform'),
9+
'sort-object-props': require.resolve('./sort-object-props/transform'),
10+
'use-named-exports': require.resolve('./use-named-exports/transform'),
11+
'use-named-imports': require.resolve('./use-named-imports/transform'),
12+
'var-to-let': require.resolve('./var-to-let/transform'),
13+
},
14+
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# import-from-root
2+
3+
Rewrite deep imports to import from a packages' root index.
4+
5+
> Set the Environment Variable `IMPORT_FROM_ROOT` to apply this transform only
6+
> to packages whose name starts with that string:
7+
> `IMPORT_FROM_ROOT=some-package yarn import-from-root <path-to-file>`
8+
9+
```js
10+
/* INPUT */
11+
import { foo } from "some-package/foo/bar/baz";
12+
13+
/* OUTPUT */
14+
import { foo } from "some-package";
15+
```
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { applyTransform } from '@codeshift/test-utils';
2+
import * as transformer from './transform';
3+
4+
describe('react@1.0.0 transform', () => {
5+
it('should transform correctly', () => {
6+
const result = applyTransform(
7+
transformer,
8+
`
9+
import foo from '<% packageName %>';
10+
console.log(foo);
11+
`,
12+
{ parser: 'tsx' },
13+
);
14+
15+
expect(result).toMatchInlineSnapshot();
16+
});
17+
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { API, FileInfo, Options } from 'jscodeshift';
2+
3+
export default function transformer(
4+
file: FileInfo,
5+
{ jscodeshift: j }: API,
6+
options: Options,
7+
) {
8+
const source = j(file.source);
9+
10+
const { IMPORT_FROM_ROOT = '' } = process.env;
11+
12+
const matchesUserFilter = importDeclaration =>
13+
IMPORT_FROM_ROOT &&
14+
importDeclaration.source.value.startsWith(IMPORT_FROM_ROOT);
15+
16+
source
17+
.find(j.ImportDeclaration)
18+
.filter(path => matchesUserFilter(path.value))
19+
.forEach(path => {
20+
const importDeclaration = path.value;
21+
const paths = importDeclaration.source.value.split('/');
22+
if (importDeclaration.source.value.startsWith('@')) {
23+
const [scope, packageName] = paths;
24+
importDeclaration.source.value = `${scope}/${packageName}`;
25+
} else {
26+
const [packageName] = paths;
27+
importDeclaration.source.value = `${packageName}`;
28+
}
29+
});
30+
31+
return source.toSource(options.printOptions);
32+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# remove-debugger
2+
3+
Removes all `debugger` statements.
4+
5+
```js
6+
/* INPUT */
7+
console.log('hello world');
8+
debugger;
9+
10+
/* OUTPUT */
11+
console.log('hello world');
12+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { applyTransform } from '@codeshift/test-utils';
2+
import * as transformer from './transform';
3+
4+
describe('react@1.0.0 transform', () => {
5+
it('should not modify files with no debugger statements', () => {
6+
const result = applyTransform(transformer, `console.log('foooo');`, {
7+
parser: 'tsx',
8+
});
9+
10+
expect(result).toMatchInlineSnapshot();
11+
});
12+
13+
it('should remove top-level debugger statement', () => {
14+
const result = applyTransform(transformer, 'debugger;', { parser: 'tsx' });
15+
16+
expect(result).toMatchInlineSnapshot();
17+
});
18+
19+
it('should debuggers in function statements', () => {
20+
const result = applyTransform(
21+
transformer,
22+
`
23+
function foo () {
24+
debugger;
25+
setTimeout(() => { debugger; console.log('foo') });debugger;
26+
}
27+
`,
28+
{ parser: 'tsx' },
29+
);
30+
31+
expect(result).toMatchInlineSnapshot();
32+
});
33+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { API, FileInfo, Options } from 'jscodeshift';
2+
3+
export default function transformer(
4+
file: FileInfo,
5+
{ jscodeshift: j }: API,
6+
options: Options,
7+
) {
8+
const source = j(file.source);
9+
const debuggerStatements = source.find(j.DebuggerStatement);
10+
11+
if (debuggerStatements.length === 0) {
12+
return file.source;
13+
}
14+
15+
debuggerStatements.remove();
16+
17+
return source.toSource(options.printOptions);
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# sort-object-props
2+
3+
Sort members of Object Literals alphabetically.
4+
5+
```js
6+
/* INPUT */
7+
const players = { messi: true, bergkamp: true, ginola: true };
8+
9+
/* OUTPUT */
10+
const players = { bergkamp: true, ginola: true, messi: true };
11+
```
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { applyTransform } from '@codeshift/test-utils';
2+
import * as transformer from './transform';
3+
4+
describe('react@1.0.0 transform', () => {
5+
it('should transform correctly', () => {
6+
const result = applyTransform(
7+
transformer,
8+
`
9+
import foo from '<% packageName %>';
10+
console.log(foo);
11+
`,
12+
{ parser: 'tsx' },
13+
);
14+
15+
expect(result).toMatchInlineSnapshot();
16+
});
17+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { API, FileInfo, Options } from 'jscodeshift';
2+
3+
export default function transformer(
4+
file: FileInfo,
5+
{ jscodeshift: j }: API,
6+
options: Options,
7+
) {
8+
const isSpreadElement = prop => prop && prop.type === 'SpreadElement';
9+
const isValue = prop => prop && prop.type !== 'SpreadElement';
10+
const getPropName = prop =>
11+
(prop.key && (prop.key.name || prop.key.value)) || '';
12+
const sortByPropName = (a, b) => {
13+
if (a < b) return -1;
14+
if (a > b) return 1;
15+
return 0;
16+
};
17+
const sortProps = props => {
18+
props.sort((a, b) => sortByPropName(getPropName(a), getPropName(b)));
19+
};
20+
21+
return j(file.source)
22+
.find(api.jscodeshift.ObjectExpression)
23+
.forEach(path => {
24+
const chunks = [];
25+
const nextProperties = [];
26+
const objectExpression = path.value;
27+
28+
objectExpression.properties.forEach((prop, i, props) => {
29+
if (isValue(prop)) {
30+
const prev = props[i - 1];
31+
const next = props[i + 1];
32+
const isChunkStart = !isValue(prev);
33+
const isChunkEnd = !isValue(next);
34+
35+
isChunkStart && chunks.push([]);
36+
const [chunk] = chunks.slice(-1);
37+
chunk.push(prop);
38+
39+
if (isChunkEnd) {
40+
sortProps(chunk);
41+
nextProperties.push(...chunk);
42+
}
43+
} else if (isSpreadElement(prop)) {
44+
nextProperties.push(prop);
45+
}
46+
});
47+
48+
objectExpression.properties = nextProperties;
49+
})
50+
.toSource(options.printOptions);
51+
}

0 commit comments

Comments
 (0)