1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | const spawn_async_1 = __importDefault(require("@expo/spawn-async"));
|
7 | const chalk_1 = __importDefault(require("chalk"));
|
8 | const globby_1 = __importDefault(require("globby"));
|
9 |
|
10 | const Runner_1 = __importDefault(require("jscodeshift/src/Runner"));
|
11 | const multimatch_1 = __importDefault(require("multimatch"));
|
12 | const path_1 = __importDefault(require("path"));
|
13 | const yargs_parser_1 = __importDefault(require("yargs-parser"));
|
14 | const jscodeshift = require.resolve('jscodeshift/bin/jscodeshift.js');
|
15 | const transformDir = path_1.default.join(__dirname, 'transforms');
|
16 | const totalStats = {};
|
17 | async function runAsync(argv) {
|
18 | const options = yargs_parser_1.default(argv);
|
19 | const [transform, ...paths] = options._.slice(2);
|
20 | const parser = options.parser;
|
21 | const transforms = await listTransformsAsync();
|
22 | if (options.help || !transform || paths.length === 0) {
|
23 | console.log(`
|
24 | Usage: expo-codemod <transform> <paths...>
|
25 |
|
26 | Options:
|
27 | <transform> (required) name of transform to apply to files
|
28 | (see a list of transforms available below)
|
29 | <paths...> one or more paths or globs (e.g. ./src/**/*.js) of sources to transform
|
30 | files in .gitignore are ignored by default
|
31 | -h, --help print this help message
|
32 | -p, --parser <babel|flow|ts|tsx> parser to use to parse the source files
|
33 | (default: babel, ts or tsx based on the file extension)
|
34 |
|
35 | Transforms available:
|
36 | ${transforms.join('\n ')}`);
|
37 | process.exit(1);
|
38 | return;
|
39 | }
|
40 | if (!transforms.includes(transform)) {
|
41 | throw new Error(`--transform: Transform ${transform} does not exist. Valid options: ` + transforms.join(', '));
|
42 | }
|
43 | const allFiles = await globby_1.default(paths, { gitignore: true, ignore: ['**/node_modules/**'] });
|
44 | if (parser) {
|
45 | console.log(`Transforming ${allFiles.length} files using parser '${parser}'...`);
|
46 | await transformAsync({ files: allFiles, parser, transform });
|
47 | }
|
48 | else {
|
49 | const jsFiles = multimatch_1.default(allFiles, ['**/*.js', '**/*.jsx']);
|
50 | if (jsFiles.length) {
|
51 | console.log(`Transforming ${jsFiles.length} JS files...`);
|
52 | await transformAsync({ files: jsFiles, parser: 'babel', transform });
|
53 | }
|
54 | const tsFiles = multimatch_1.default(allFiles, ['**/*.ts']);
|
55 | if (tsFiles.length) {
|
56 | console.log(`Transforming ${tsFiles.length} TS files...`);
|
57 | await transformAsync({ files: tsFiles, parser: 'ts', transform });
|
58 | }
|
59 | const tsxFiles = multimatch_1.default(allFiles, ['**/*.tsx']);
|
60 | if (tsxFiles.length) {
|
61 | console.log(`Transforming ${tsxFiles.length} TSX files...`);
|
62 | await transformAsync({ files: tsxFiles, parser: 'tsx', transform });
|
63 | }
|
64 | }
|
65 | if (transform === 'sdk33-imports' || transform === 'sdk37-imports') {
|
66 | const packages = Object.keys(totalStats).sort();
|
67 | if (packages.length) {
|
68 | console.log(chalk_1.default.bold(`\n🆕 Added imports from ${packages.length} packages. Installing packages with \`expo install\`...`));
|
69 | console.log(`> expo install ${packages.join(' ')}`);
|
70 | try {
|
71 | await spawn_async_1.default('expo', ['install', ...packages], { stdio: 'inherit' });
|
72 | }
|
73 | catch (error) {
|
74 | console.error(chalk_1.default.red('\n⚠️ expo install failed.'));
|
75 | console.log(chalk_1.default.dim(error.stack));
|
76 | console.error(chalk_1.default.red('To finish the codemod, please install the added packages manually using:'));
|
77 | console.log(chalk_1.default.bold.red(`> expo install ${packages.join(' ')}`));
|
78 | process.exit(1);
|
79 | }
|
80 | }
|
81 | }
|
82 | }
|
83 | exports.runAsync = runAsync;
|
84 | async function transformAsync({ files, parser, transform, }) {
|
85 | const transformFile = path_1.default.join(transformDir, `${transform}.js`);
|
86 | if (transform === 'sdk33-imports' || transform === 'sdk37-imports') {
|
87 |
|
88 | const { stats } = await Runner_1.default.run(transformFile, files, {
|
89 | dry: true,
|
90 | silent: true,
|
91 | babel: false,
|
92 | parser,
|
93 | });
|
94 | Object.keys(stats).forEach(key => {
|
95 | totalStats[key] = (totalStats[key] || 0) + stats[key];
|
96 | });
|
97 | }
|
98 | const args = ['--parser', parser, '--transform', transformFile, '--no-babel', ...files];
|
99 | return await spawn_async_1.default(jscodeshift, args, { stdio: 'inherit' });
|
100 | }
|
101 | async function listTransformsAsync() {
|
102 | const modules = await globby_1.default(['*.js'], { cwd: transformDir });
|
103 | return modules.map(filename => path_1.default.basename(filename, '.js'));
|
104 | }
|
105 |
|
\ | No newline at end of file |