@next/codemod 15.0.0-canary.17 → 15.0.0-canary.170
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/next-codemod.js +27 -3
- package/bin/transform.js +104 -0
- package/bin/upgrade.js +224 -0
- package/lib/codemods.js +103 -0
- package/lib/cra-to-next/global-css-transform.js +2 -3
- package/lib/cra-to-next/index-to-component.js +2 -3
- package/lib/handle-package.js +76 -0
- package/lib/install.js +2 -3
- package/lib/run-jscodeshift.js +9 -2
- package/lib/utils.js +92 -0
- package/package.json +8 -5
- package/transforms/add-missing-react-import.js +1 -1
- package/transforms/built-in-next-font.js +1 -1
- package/transforms/cra-to-next.js +238 -236
- package/transforms/lib/async-request-api/index.js +21 -0
- package/transforms/lib/async-request-api/next-async-dynamic-api.js +221 -0
- package/transforms/lib/async-request-api/next-async-dynamic-prop.js +345 -0
- package/transforms/lib/async-request-api/utils.js +198 -0
- package/transforms/metadata-to-viewport-export.js +1 -1
- package/transforms/name-default-component.js +3 -4
- package/transforms/new-link.js +5 -4
- package/transforms/next-async-request-api.js +9 -0
- package/transforms/next-dynamic-access-named-export.js +65 -0
- package/transforms/next-image-experimental.js +9 -13
- package/transforms/next-image-to-legacy-image.js +5 -7
- package/transforms/next-og-import.js +1 -1
- package/transforms/next-request-geo-ip.js +338 -0
- package/transforms/url-to-withrouter.js +1 -1
- package/transforms/withamp-to-config.js +1 -1
- package/bin/cli.js +0 -216
- package/lib/uninstall-package.js +0 -32
package/bin/next-codemod.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
2
3
|
/**
|
|
3
4
|
* Copyright 2015-present, Facebook, Inc.
|
|
4
5
|
*
|
|
@@ -6,7 +7,30 @@
|
|
|
6
7
|
* LICENSE file in the root directory of this source tree.
|
|
7
8
|
*
|
|
8
9
|
*/
|
|
9
|
-
// Based on https://github.com/reactjs/react-codemod/blob/dd8671c9a470a2c342b221ec903c574cf31e9f57/bin/
|
|
10
|
-
// next
|
|
11
|
-
|
|
10
|
+
// Based on https://github.com/reactjs/react-codemod/blob/dd8671c9a470a2c342b221ec903c574cf31e9f57/bin/cli.js
|
|
11
|
+
// @next/codemod optional-name-of-transform optional/path/to/src [...options]
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
const commander_1 = require("commander");
|
|
14
|
+
const upgrade_1 = require("./upgrade");
|
|
15
|
+
const transform_1 = require("./transform");
|
|
16
|
+
const packageJson = require('../package.json');
|
|
17
|
+
const program = new commander_1.Command(packageJson.name)
|
|
18
|
+
.description('Codemods for updating Next.js apps.')
|
|
19
|
+
.version(packageJson.version, '-v, --version', 'Output the current version of @next/codemod.')
|
|
20
|
+
.argument('[codemod]', 'Codemod slug to run. See "https://github.com/vercel/next.js/tree/canary/packages/next-codemod".')
|
|
21
|
+
.argument('[source]', 'Path to source files or directory to transform including glob patterns.')
|
|
22
|
+
.usage('[codemod] [source] [options]')
|
|
23
|
+
.helpOption('-h, --help', 'Display this help message.')
|
|
24
|
+
.option('-f, --force', 'Bypass Git safety checks and forcibly run codemods')
|
|
25
|
+
.option('-d, --dry', 'Dry run (no changes are made to files)')
|
|
26
|
+
.option('-p, --print', 'Print transformed files to your terminal')
|
|
27
|
+
.option('-j, --jscodeshift', '(Advanced) Pass options directly to jscodeshift')
|
|
28
|
+
.action(transform_1.runTransform)
|
|
29
|
+
.allowUnknownOption();
|
|
30
|
+
program
|
|
31
|
+
.command('upgrade')
|
|
32
|
+
.description('Upgrade Next.js apps to desired versions with a single command.')
|
|
33
|
+
.usage('[options]')
|
|
34
|
+
.action(upgrade_1.runUpgrade);
|
|
35
|
+
program.parse(process.argv);
|
|
12
36
|
//# sourceMappingURL=next-codemod.js.map
|
package/bin/transform.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
exports.transformerDirectory = exports.jscodeshiftExecutable = void 0;
|
|
7
|
+
exports.runTransform = runTransform;
|
|
8
|
+
const execa_1 = __importDefault(require("execa"));
|
|
9
|
+
const globby_1 = __importDefault(require("globby"));
|
|
10
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
11
|
+
const node_path_1 = require("node:path");
|
|
12
|
+
const handle_package_1 = require("../lib/handle-package");
|
|
13
|
+
const utils_1 = require("../lib/utils");
|
|
14
|
+
function expandFilePathsIfNeeded(filesBeforeExpansion) {
|
|
15
|
+
const shouldExpandFiles = filesBeforeExpansion.some((file) => file.includes('*'));
|
|
16
|
+
return shouldExpandFiles
|
|
17
|
+
? globby_1.default.sync(filesBeforeExpansion)
|
|
18
|
+
: filesBeforeExpansion;
|
|
19
|
+
}
|
|
20
|
+
exports.jscodeshiftExecutable = require.resolve('.bin/jscodeshift');
|
|
21
|
+
exports.transformerDirectory = (0, node_path_1.join)(__dirname, '../', 'transforms');
|
|
22
|
+
async function runTransform(transform, path, options) {
|
|
23
|
+
let transformer = transform;
|
|
24
|
+
let directory = path;
|
|
25
|
+
if (!options.dry) {
|
|
26
|
+
(0, utils_1.checkGitStatus)(options.force);
|
|
27
|
+
}
|
|
28
|
+
if (transform &&
|
|
29
|
+
!utils_1.TRANSFORMER_INQUIRER_CHOICES.find((x) => x.value === transform)) {
|
|
30
|
+
console.error('Invalid transform choice, pick one of:');
|
|
31
|
+
console.error(utils_1.TRANSFORMER_INQUIRER_CHOICES.map((x) => '- ' + x.value).join('\n'));
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
if (!path) {
|
|
35
|
+
const res = await (0, prompts_1.default)({
|
|
36
|
+
type: 'text',
|
|
37
|
+
name: 'path',
|
|
38
|
+
message: 'On which files or directory should the codemods be applied?',
|
|
39
|
+
default: '.',
|
|
40
|
+
});
|
|
41
|
+
directory = res.path;
|
|
42
|
+
}
|
|
43
|
+
if (!transform) {
|
|
44
|
+
const res = await (0, prompts_1.default)({
|
|
45
|
+
type: 'select',
|
|
46
|
+
name: 'transformer',
|
|
47
|
+
message: 'Which transform would you like to apply?',
|
|
48
|
+
choices: utils_1.TRANSFORMER_INQUIRER_CHOICES,
|
|
49
|
+
});
|
|
50
|
+
transformer = res.transformer;
|
|
51
|
+
}
|
|
52
|
+
const filesExpanded = expandFilePathsIfNeeded([directory]);
|
|
53
|
+
if (!filesExpanded.length) {
|
|
54
|
+
console.log(`No files found matching "${directory}"`);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const transformerPath = (0, node_path_1.join)(exports.transformerDirectory, `${transformer}.js`);
|
|
58
|
+
if (transformer === 'cra-to-next') {
|
|
59
|
+
// cra-to-next transform doesn't use jscodeshift directly
|
|
60
|
+
return require(transformerPath).default(filesExpanded, options);
|
|
61
|
+
}
|
|
62
|
+
let args = [];
|
|
63
|
+
const { dry, print, runInBand, jscodeshift } = options;
|
|
64
|
+
if (dry) {
|
|
65
|
+
args.push('--dry');
|
|
66
|
+
}
|
|
67
|
+
if (print) {
|
|
68
|
+
args.push('--print');
|
|
69
|
+
}
|
|
70
|
+
if (runInBand) {
|
|
71
|
+
args.push('--run-in-band');
|
|
72
|
+
}
|
|
73
|
+
args.push('--verbose=2');
|
|
74
|
+
args.push('--ignore-pattern=**/node_modules/**');
|
|
75
|
+
args.push('--ignore-pattern=**/.next/**');
|
|
76
|
+
args.push('--extensions=tsx,ts,jsx,js');
|
|
77
|
+
args = args.concat(['--transform', transformerPath]);
|
|
78
|
+
if (jscodeshift) {
|
|
79
|
+
args = args.concat(jscodeshift);
|
|
80
|
+
}
|
|
81
|
+
args = args.concat(filesExpanded);
|
|
82
|
+
console.log(`Executing command: jscodeshift ${args.join(' ')}`);
|
|
83
|
+
const result = execa_1.default.sync(exports.jscodeshiftExecutable, args, {
|
|
84
|
+
stdio: 'inherit',
|
|
85
|
+
stripFinalNewline: false,
|
|
86
|
+
});
|
|
87
|
+
if (result.failed) {
|
|
88
|
+
throw new Error(`jscodeshift exited with code ${result.exitCode}`);
|
|
89
|
+
}
|
|
90
|
+
if (!dry && transformer === 'built-in-next-font') {
|
|
91
|
+
console.log('Uninstalling `@next/font`');
|
|
92
|
+
try {
|
|
93
|
+
(0, handle_package_1.uninstallPackage)('@next/font');
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
console.error("Couldn't uninstall `@next/font`, please uninstall it manually");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (!dry && transformer === 'next-request-geo-ip') {
|
|
100
|
+
console.log('Installing `@vercel/functions`...');
|
|
101
|
+
(0, handle_package_1.installPackage)('@vercel/functions');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=transform.js.map
|
package/bin/upgrade.js
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
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
|
+
exports.runUpgrade = runUpgrade;
|
|
7
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const compare_versions_1 = require("compare-versions");
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
const codemods_1 = require("../lib/codemods");
|
|
14
|
+
const handle_package_1 = require("../lib/handle-package");
|
|
15
|
+
async function runUpgrade() {
|
|
16
|
+
const appPackageJsonPath = path_1.default.resolve(process.cwd(), 'package.json');
|
|
17
|
+
let appPackageJson = JSON.parse(fs_1.default.readFileSync(appPackageJsonPath, 'utf8'));
|
|
18
|
+
await detectWorkspace(appPackageJson);
|
|
19
|
+
let targetNextPackageJson;
|
|
20
|
+
let targetVersionSpecifier = '';
|
|
21
|
+
const shortcutVersion = process.argv[2]?.replace('@', '');
|
|
22
|
+
if (shortcutVersion) {
|
|
23
|
+
const res = await fetch(`https://registry.npmjs.org/next/${shortcutVersion}`);
|
|
24
|
+
if (res.status === 200) {
|
|
25
|
+
targetNextPackageJson = await res.json();
|
|
26
|
+
targetVersionSpecifier = targetNextPackageJson.version;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.error(`${chalk_1.default.yellow('Next.js ' + shortcutVersion)} does not exist. Check available versions at ${chalk_1.default.underline('https://www.npmjs.com/package/next?activeTab=versions')}, or choose one from below\n`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const installedNextVersion = await getInstalledNextVersion();
|
|
33
|
+
if (!targetNextPackageJson) {
|
|
34
|
+
let nextPackageJson = {};
|
|
35
|
+
try {
|
|
36
|
+
const resCanary = await fetch(`https://registry.npmjs.org/next/canary`);
|
|
37
|
+
nextPackageJson['canary'] = await resCanary.json();
|
|
38
|
+
const resRc = await fetch(`https://registry.npmjs.org/next/rc`);
|
|
39
|
+
nextPackageJson['rc'] = await resRc.json();
|
|
40
|
+
const resLatest = await fetch(`https://registry.npmjs.org/next/latest`);
|
|
41
|
+
nextPackageJson['latest'] = await resLatest.json();
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error('Failed to fetch versions from npm registry.');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
let showRc = true;
|
|
48
|
+
if (nextPackageJson['latest'].version && nextPackageJson['rc'].version) {
|
|
49
|
+
showRc =
|
|
50
|
+
(0, compare_versions_1.compareVersions)(nextPackageJson['rc'].version, nextPackageJson['latest'].version) === 1;
|
|
51
|
+
}
|
|
52
|
+
const choices = [
|
|
53
|
+
{
|
|
54
|
+
title: 'Canary',
|
|
55
|
+
value: 'canary',
|
|
56
|
+
description: `Experimental version with latest features (${nextPackageJson['canary'].version})`,
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
if (showRc) {
|
|
60
|
+
choices.push({
|
|
61
|
+
title: 'Release Candidate',
|
|
62
|
+
value: 'rc',
|
|
63
|
+
description: `Pre-release version for final testing (${nextPackageJson['rc'].version})`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
choices.push({
|
|
67
|
+
title: 'Stable',
|
|
68
|
+
value: 'latest',
|
|
69
|
+
description: `Production-ready release (${nextPackageJson['latest'].version})`,
|
|
70
|
+
});
|
|
71
|
+
if (installedNextVersion) {
|
|
72
|
+
console.log(`You are currently using ${chalk_1.default.blue('Next.js ' + installedNextVersion)}`);
|
|
73
|
+
}
|
|
74
|
+
const initialVersionSpecifierIdx = await getVersionSpecifierIdx(installedNextVersion, showRc);
|
|
75
|
+
const response = await (0, prompts_1.default)({
|
|
76
|
+
type: 'select',
|
|
77
|
+
name: 'version',
|
|
78
|
+
message: 'What Next.js version do you want to upgrade to?',
|
|
79
|
+
choices: choices,
|
|
80
|
+
initial: initialVersionSpecifierIdx,
|
|
81
|
+
}, { onCancel: () => process.exit(0) });
|
|
82
|
+
targetNextPackageJson = nextPackageJson[response.version];
|
|
83
|
+
targetVersionSpecifier = response.version;
|
|
84
|
+
}
|
|
85
|
+
const targetNextVersion = targetNextPackageJson.version;
|
|
86
|
+
if (targetNextVersion &&
|
|
87
|
+
(0, compare_versions_1.compareVersions)(targetNextVersion, '15.0.0-canary') >= 0) {
|
|
88
|
+
await suggestTurbopack(appPackageJson);
|
|
89
|
+
}
|
|
90
|
+
fs_1.default.writeFileSync(appPackageJsonPath, JSON.stringify(appPackageJson, null, 2));
|
|
91
|
+
const packageManager = (0, handle_package_1.getPkgManager)(process.cwd());
|
|
92
|
+
const nextDependency = `next@${targetNextVersion}`;
|
|
93
|
+
const reactDependencies = [
|
|
94
|
+
`react@${targetNextPackageJson.peerDependencies['react']}`,
|
|
95
|
+
`@types/react@${targetNextPackageJson.devDependencies['@types/react']}`,
|
|
96
|
+
`react-dom@${targetNextPackageJson.peerDependencies['react-dom']}`,
|
|
97
|
+
`@types/react-dom@${targetNextPackageJson.devDependencies['@types/react-dom']}`,
|
|
98
|
+
];
|
|
99
|
+
(0, handle_package_1.installPackage)([nextDependency, ...reactDependencies], packageManager);
|
|
100
|
+
console.log(`Upgrading your project to ${chalk_1.default.blue('Next.js ' + targetVersionSpecifier)}...\n`);
|
|
101
|
+
await suggestCodemods(installedNextVersion, targetNextVersion);
|
|
102
|
+
console.log(`\n${chalk_1.default.green('✔')} Your Next.js project has been upgraded successfully. ${chalk_1.default.bold('Time to ship! 🚢')}`);
|
|
103
|
+
}
|
|
104
|
+
async function detectWorkspace(appPackageJson) {
|
|
105
|
+
let isWorkspace = appPackageJson.workspaces ||
|
|
106
|
+
fs_1.default.existsSync(path_1.default.resolve(process.cwd(), 'pnpm-workspace.yaml'));
|
|
107
|
+
if (!isWorkspace)
|
|
108
|
+
return;
|
|
109
|
+
console.log(`${chalk_1.default.red('⚠️')} You seem to be in the root of a monorepo. ${chalk_1.default.blue('@next/upgrade')} should be run in a specific app directory within the monorepo.`);
|
|
110
|
+
const response = await (0, prompts_1.default)({
|
|
111
|
+
type: 'confirm',
|
|
112
|
+
name: 'value',
|
|
113
|
+
message: 'Do you still want to continue?',
|
|
114
|
+
initial: false,
|
|
115
|
+
}, { onCancel: () => process.exit(0) });
|
|
116
|
+
if (!response.value) {
|
|
117
|
+
process.exit(0);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function getInstalledNextVersion() {
|
|
121
|
+
const installedNextPackageJsonDir = require.resolve('next/package.json', {
|
|
122
|
+
paths: [process.cwd()],
|
|
123
|
+
});
|
|
124
|
+
const installedNextPackageJson = JSON.parse(fs_1.default.readFileSync(installedNextPackageJsonDir, 'utf8'));
|
|
125
|
+
return installedNextPackageJson.version;
|
|
126
|
+
}
|
|
127
|
+
/*
|
|
128
|
+
* Returns the index of the current version's specifier in the
|
|
129
|
+
* array ['canary', 'rc', 'latest'] or ['canary', 'latest']
|
|
130
|
+
*/
|
|
131
|
+
async function getVersionSpecifierIdx(installedNextVersion, showRc) {
|
|
132
|
+
if (installedNextVersion == null) {
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
if (installedNextVersion.includes('canary')) {
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
if (installedNextVersion.includes('rc')) {
|
|
139
|
+
return 1;
|
|
140
|
+
}
|
|
141
|
+
return showRc ? 2 : 1;
|
|
142
|
+
}
|
|
143
|
+
/*
|
|
144
|
+
* Heuristics are used to determine whether to Turbopack is enabled or not and
|
|
145
|
+
* to determine how to update the dev script.
|
|
146
|
+
*
|
|
147
|
+
* 1. If the dev script contains `--turbo` option, we assume that Turbopack is
|
|
148
|
+
* already enabled.
|
|
149
|
+
* 2. If the dev script contains the string `next dev`, we replace it to
|
|
150
|
+
* `next dev --turbo`.
|
|
151
|
+
* 3. Otherwise, we ask the user to manually add `--turbo` to their dev command,
|
|
152
|
+
* showing the current dev command as the initial value.
|
|
153
|
+
*/
|
|
154
|
+
async function suggestTurbopack(packageJson) {
|
|
155
|
+
const devScript = packageJson.scripts['dev'];
|
|
156
|
+
if (devScript.includes('--turbo'))
|
|
157
|
+
return;
|
|
158
|
+
const responseTurbopack = await (0, prompts_1.default)({
|
|
159
|
+
type: 'confirm',
|
|
160
|
+
name: 'enable',
|
|
161
|
+
message: 'Turbopack is now the stable default for dev mode. Enable it?',
|
|
162
|
+
initial: true,
|
|
163
|
+
}, {
|
|
164
|
+
onCancel: () => {
|
|
165
|
+
process.exit(0);
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
if (!responseTurbopack.enable) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (devScript.includes('next dev')) {
|
|
172
|
+
packageJson.scripts['dev'] = devScript.replace('next dev', 'next dev --turbo');
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const responseCustomDevScript = await (0, prompts_1.default)({
|
|
176
|
+
type: 'text',
|
|
177
|
+
name: 'customDevScript',
|
|
178
|
+
message: 'Please add `--turbo` to your dev command:',
|
|
179
|
+
initial: devScript,
|
|
180
|
+
});
|
|
181
|
+
packageJson.scripts['dev'] =
|
|
182
|
+
responseCustomDevScript.customDevScript || devScript;
|
|
183
|
+
}
|
|
184
|
+
async function suggestCodemods(initialNextVersion, targetNextVersion) {
|
|
185
|
+
const initialVersionIndex = codemods_1.availableCodemods.findIndex((versionCodemods) => (0, compare_versions_1.compareVersions)(versionCodemods.version, initialNextVersion) > 0);
|
|
186
|
+
if (initialVersionIndex === -1) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
let targetVersionIndex = codemods_1.availableCodemods.findIndex((versionCodemods) => (0, compare_versions_1.compareVersions)(versionCodemods.version, targetNextVersion) > 0);
|
|
190
|
+
if (targetVersionIndex === -1) {
|
|
191
|
+
targetVersionIndex = codemods_1.availableCodemods.length;
|
|
192
|
+
}
|
|
193
|
+
const relevantCodemods = codemods_1.availableCodemods
|
|
194
|
+
.slice(initialVersionIndex, targetVersionIndex)
|
|
195
|
+
.flatMap((versionCodemods) => versionCodemods.codemods);
|
|
196
|
+
if (relevantCodemods.length === 0) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
let codemodsString = `\nThe following ${chalk_1.default.blue('codemods')} are available for your upgrade:`;
|
|
200
|
+
relevantCodemods.forEach((codemod) => {
|
|
201
|
+
codemodsString += `\n- ${codemod.title} ${chalk_1.default.gray(`(${codemod.value})`)}`;
|
|
202
|
+
});
|
|
203
|
+
codemodsString += '\n';
|
|
204
|
+
console.log(codemodsString);
|
|
205
|
+
const responseCodemods = await (0, prompts_1.default)({
|
|
206
|
+
type: 'confirm',
|
|
207
|
+
name: 'apply',
|
|
208
|
+
message: `Do you want to apply these codemods?`,
|
|
209
|
+
initial: true,
|
|
210
|
+
}, {
|
|
211
|
+
onCancel: () => {
|
|
212
|
+
process.exit(0);
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
if (!responseCodemods.apply) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
for (const codemod of relevantCodemods) {
|
|
219
|
+
(0, child_process_1.execSync)(`npx @next/codemod@latest ${codemod.value} ${process.cwd()} --force`, {
|
|
220
|
+
stdio: 'inherit',
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=upgrade.js.map
|
package/lib/codemods.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.availableCodemods = void 0;
|
|
4
|
+
exports.availableCodemods = [
|
|
5
|
+
{
|
|
6
|
+
version: '6',
|
|
7
|
+
codemods: [
|
|
8
|
+
{
|
|
9
|
+
title: 'Use withRouter',
|
|
10
|
+
value: 'url-to-withrouter',
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
version: '8',
|
|
16
|
+
codemods: [
|
|
17
|
+
{
|
|
18
|
+
title: 'Transform AMP HOC into page config',
|
|
19
|
+
value: 'withamp-to-config',
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
version: '9',
|
|
25
|
+
codemods: [
|
|
26
|
+
{
|
|
27
|
+
title: 'Transform Anonymous Components into Named Components',
|
|
28
|
+
value: 'name-default-component',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
version: '10',
|
|
34
|
+
codemods: [
|
|
35
|
+
{
|
|
36
|
+
title: 'Add React Import',
|
|
37
|
+
value: 'add-missing-react-import',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
version: '11',
|
|
43
|
+
codemods: [
|
|
44
|
+
{
|
|
45
|
+
title: 'Migrate from CRA',
|
|
46
|
+
value: 'cra-to-next',
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
version: '13.0',
|
|
52
|
+
codemods: [
|
|
53
|
+
{
|
|
54
|
+
title: 'Remove <a> Tags From Link Components',
|
|
55
|
+
value: 'new-link',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
title: 'Migrate to the New Image Component',
|
|
59
|
+
value: 'next-image-experimental',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
title: 'Rename Next Image Imports',
|
|
63
|
+
value: 'next-image-to-legacy-image',
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
version: '13.2',
|
|
69
|
+
codemods: [
|
|
70
|
+
{
|
|
71
|
+
title: 'Use Built-in Font',
|
|
72
|
+
value: 'built-in-next-font',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
version: '14.0',
|
|
78
|
+
codemods: [
|
|
79
|
+
{
|
|
80
|
+
title: 'Migrate ImageResponse imports',
|
|
81
|
+
value: 'next-og-import',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: 'Use viewport export',
|
|
85
|
+
value: 'metadata-to-viewport-export',
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
version: '15.0',
|
|
91
|
+
codemods: [
|
|
92
|
+
{
|
|
93
|
+
title: 'Transforms usage of Next.js async Request APIs',
|
|
94
|
+
value: 'next-async-request-api',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
title: 'Migrate `geo` and `ip` properties on `NextRequest`',
|
|
98
|
+
value: 'next-request-geo-ip',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
//# sourceMappingURL=codemods.js.map
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.globalCssContext = void 0;
|
|
7
|
+
exports.default = transformer;
|
|
7
8
|
const path_1 = __importDefault(require("path"));
|
|
8
9
|
exports.globalCssContext = {
|
|
9
10
|
cssImports: new Set(),
|
|
@@ -37,8 +38,7 @@ function transformer(file, api, options) {
|
|
|
37
38
|
}
|
|
38
39
|
else if (value.endsWith('.svg')) {
|
|
39
40
|
const isComponentImport = path.node.specifiers.some((specifier) => {
|
|
40
|
-
|
|
41
|
-
return ((_a = specifier.imported) === null || _a === void 0 ? void 0 : _a.name) === 'ReactComponent';
|
|
41
|
+
return specifier.imported?.name === 'ReactComponent';
|
|
42
42
|
});
|
|
43
43
|
if (isComponentImport) {
|
|
44
44
|
exports.globalCssContext.reactSvgImports.add(file.path);
|
|
@@ -52,5 +52,4 @@ function transformer(file, api, options) {
|
|
|
52
52
|
? root.toSource(options)
|
|
53
53
|
: null;
|
|
54
54
|
}
|
|
55
|
-
exports.default = transformer;
|
|
56
55
|
//# sourceMappingURL=global-css-transform.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.indexContext = void 0;
|
|
4
|
+
exports.default = transformer;
|
|
4
5
|
exports.indexContext = {
|
|
5
6
|
multipleRenderRoots: false,
|
|
6
7
|
nestedRender: false,
|
|
@@ -28,7 +29,6 @@ function transformer(file, api, options) {
|
|
|
28
29
|
root
|
|
29
30
|
.find(j.CallExpression)
|
|
30
31
|
.filter((path) => {
|
|
31
|
-
var _a, _b;
|
|
32
32
|
const { node } = path;
|
|
33
33
|
let found = false;
|
|
34
34
|
if (defaultReactDomImport &&
|
|
@@ -43,7 +43,7 @@ function transformer(file, api, options) {
|
|
|
43
43
|
if (found) {
|
|
44
44
|
foundReactRender++;
|
|
45
45
|
hasModifications = true;
|
|
46
|
-
if (!Array.isArray(
|
|
46
|
+
if (!Array.isArray(path.parentPath?.parentPath?.value)) {
|
|
47
47
|
exports.indexContext.nestedRender = true;
|
|
48
48
|
return false;
|
|
49
49
|
}
|
|
@@ -73,5 +73,4 @@ function transformer(file, api, options) {
|
|
|
73
73
|
// }).remove()
|
|
74
74
|
return hasModifications ? root.toSource(options) : null;
|
|
75
75
|
}
|
|
76
|
-
exports.default = transformer;
|
|
77
76
|
//# sourceMappingURL=index-to-component.js.map
|
|
@@ -0,0 +1,76 @@
|
|
|
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
|
+
exports.getPkgManager = getPkgManager;
|
|
7
|
+
exports.uninstallPackage = uninstallPackage;
|
|
8
|
+
exports.installPackage = installPackage;
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const execa_1 = __importDefault(require("execa"));
|
|
12
|
+
function getPkgManager(baseDir) {
|
|
13
|
+
try {
|
|
14
|
+
for (const { lockFile, packageManager } of [
|
|
15
|
+
{ lockFile: 'yarn.lock', packageManager: 'yarn' },
|
|
16
|
+
{ lockFile: 'pnpm-lock.yaml', packageManager: 'pnpm' },
|
|
17
|
+
{ lockFile: 'package-lock.json', packageManager: 'npm' },
|
|
18
|
+
{ lockFile: 'bun.lockb', packageManager: 'bun' },
|
|
19
|
+
]) {
|
|
20
|
+
if (fs_1.default.existsSync(path_1.default.join(baseDir, lockFile))) {
|
|
21
|
+
return packageManager;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
25
|
+
if (userAgent) {
|
|
26
|
+
if (userAgent.startsWith('yarn')) {
|
|
27
|
+
return 'yarn';
|
|
28
|
+
}
|
|
29
|
+
else if (userAgent.startsWith('pnpm')) {
|
|
30
|
+
return 'pnpm';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
execa_1.default.sync('yarn --version', { stdio: 'ignore' });
|
|
35
|
+
return 'yarn';
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
try {
|
|
39
|
+
execa_1.default.sync('pnpm --version', { stdio: 'ignore' });
|
|
40
|
+
return 'pnpm';
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
execa_1.default.sync('bun --version', { stdio: 'ignore' });
|
|
44
|
+
return 'bun';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return 'npm';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function uninstallPackage(packageToUninstall, pkgManager) {
|
|
53
|
+
pkgManager ??= getPkgManager(process.cwd());
|
|
54
|
+
if (!pkgManager)
|
|
55
|
+
throw new Error('Failed to find package manager');
|
|
56
|
+
let command = 'uninstall';
|
|
57
|
+
if (pkgManager === 'yarn') {
|
|
58
|
+
command = 'remove';
|
|
59
|
+
}
|
|
60
|
+
execa_1.default.sync(pkgManager, [command, packageToUninstall], { stdio: 'inherit' });
|
|
61
|
+
}
|
|
62
|
+
function installPackage(packageToInstall, pkgManager) {
|
|
63
|
+
pkgManager ??= getPkgManager(process.cwd());
|
|
64
|
+
if (!pkgManager)
|
|
65
|
+
throw new Error('Failed to find package manager');
|
|
66
|
+
if (Array.isArray(packageToInstall)) {
|
|
67
|
+
packageToInstall = packageToInstall.join(' ');
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
execa_1.default.sync(pkgManager, ['add', packageToInstall], { stdio: 'inherit' });
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw new Error(`Failed to install "${packageToInstall}". Please install it manually.`, { cause: error });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=handle-package.js.map
|
package/lib/install.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.install =
|
|
6
|
+
exports.install = install;
|
|
7
7
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
8
8
|
const picocolors_1 = require("picocolors");
|
|
9
9
|
const cross_spawn_1 = __importDefault(require("cross-spawn"));
|
|
@@ -84,7 +84,7 @@ function install(root, dependencies, { useYarn, isOnline, devDependencies }) {
|
|
|
84
84
|
*/
|
|
85
85
|
const child = (0, cross_spawn_1.default)(command, args, {
|
|
86
86
|
stdio: 'inherit',
|
|
87
|
-
env:
|
|
87
|
+
env: { ...process.env, ADBLOCK: '1', DISABLE_OPENCOLLECTIVE: '1' },
|
|
88
88
|
});
|
|
89
89
|
child.on('close', (code) => {
|
|
90
90
|
if (code !== 0) {
|
|
@@ -95,5 +95,4 @@ function install(root, dependencies, { useYarn, isOnline, devDependencies }) {
|
|
|
95
95
|
});
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
|
-
exports.install = install;
|
|
99
98
|
//# sourceMappingURL=install.js.map
|
package/lib/run-jscodeshift.js
CHANGED
|
@@ -3,12 +3,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = runJscodeshift;
|
|
6
7
|
// @ts-ignore internal module
|
|
7
8
|
const Runner_1 = __importDefault(require("jscodeshift/src/Runner"));
|
|
8
9
|
function runJscodeshift(transformerPath, flags, files) {
|
|
9
10
|
// we run jscodeshift in the same process to be able to
|
|
10
11
|
// share state between the main CRA transform and sub-transforms
|
|
11
|
-
return Runner_1.default.run(transformerPath, files,
|
|
12
|
+
return Runner_1.default.run(transformerPath, files, {
|
|
13
|
+
ignorePattern: ['**/node_modules/**', '**/.next/**', '**/build/**'],
|
|
14
|
+
extensions: 'tsx,ts,jsx,js',
|
|
15
|
+
parser: 'tsx',
|
|
16
|
+
verbose: 2,
|
|
17
|
+
runInBand: true,
|
|
18
|
+
...flags,
|
|
19
|
+
});
|
|
12
20
|
}
|
|
13
|
-
exports.default = runJscodeshift;
|
|
14
21
|
//# sourceMappingURL=run-jscodeshift.js.map
|