-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathjavaScriptCodemod.ts
More file actions
56 lines (46 loc) · 1.88 KB
/
javaScriptCodemod.ts
File metadata and controls
56 lines (46 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import {File} from '@babel/types';
import {parse, print} from 'recast';
import {parse as babelParse} from '@babel/parser';
import getBabelOptionsModule from 'recast/parsers/_babel_options.js';
import type {Overrides} from 'recast/parsers/_babel_options.js';
import {Codemod, CodemodOptions, ResultCode} from '@/application/project/code/transformation/codemod';
import {Language} from '@/application/project/code/transformation/javascript/utils/parse';
export type Configuration<O extends CodemodOptions> = {
codemod: Codemod<File, O>,
languages: Language[],
};
// This is a workaround mixed ESM and CommonJS modules that causes issues
// when bundling the recast package.
const getBabelOptions = 'default' in getBabelOptionsModule
? getBabelOptionsModule.default as typeof getBabelOptionsModule
: getBabelOptionsModule;
export class JavaScriptCodemod<O extends CodemodOptions> implements Codemod<string, O> {
private readonly codemod: Codemod<File, O>;
public constructor(configuration: Configuration<O>) {
this.codemod = configuration.codemod;
}
public async apply(input: string, options?: O): Promise<ResultCode<string>> {
const ast = parse(input, {
parser: {
parse: (source: string, parseOptions?: Overrides) => {
const babelOptions = getBabelOptions(parseOptions);
babelOptions.plugins.push('jsx', 'typescript');
return babelParse(source, babelOptions);
},
},
});
const result = await this.codemod.apply(ast, options);
if (!result.modified) {
return {
modified: false,
result: input,
};
}
return {
modified: true,
result: print(result.result, {
reuseWhitespace: false,
}).code,
};
}
}