@next/codemod 15.0.0-canary.190 → 15.0.0-canary.192
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 +15 -1
- package/bin/shared.js +7 -0
- package/bin/upgrade.js +54 -16
- package/lib/handle-package.js +27 -3
- package/package.json +3 -2
package/bin/next-codemod.js
CHANGED
|
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
const commander_1 = require("commander");
|
|
14
14
|
const upgrade_1 = require("./upgrade");
|
|
15
15
|
const transform_1 = require("./transform");
|
|
16
|
+
const shared_1 = require("./shared");
|
|
16
17
|
const packageJson = require('../package.json');
|
|
17
18
|
const program = new commander_1.Command(packageJson.name)
|
|
18
19
|
.description('Codemods for updating Next.js apps.')
|
|
@@ -45,6 +46,19 @@ program
|
|
|
45
46
|
: 'latest')
|
|
46
47
|
.usage('[revision] [options]')
|
|
47
48
|
.option('--verbose', 'Verbose output', false)
|
|
48
|
-
.action(
|
|
49
|
+
.action(async (revision, options) => {
|
|
50
|
+
try {
|
|
51
|
+
await (0, upgrade_1.runUpgrade)(revision, options);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (!options.verbose && error instanceof shared_1.BadInput) {
|
|
55
|
+
console.error(error.message);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.error(error);
|
|
59
|
+
}
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
49
63
|
program.parse(process.argv);
|
|
50
64
|
//# sourceMappingURL=next-codemod.js.map
|
package/bin/shared.js
ADDED
package/bin/upgrade.js
CHANGED
|
@@ -14,6 +14,7 @@ const picocolors_1 = __importDefault(require("picocolors"));
|
|
|
14
14
|
const handle_package_1 = require("../lib/handle-package");
|
|
15
15
|
const transform_1 = require("./transform");
|
|
16
16
|
const utils_1 = require("../lib/utils");
|
|
17
|
+
const shared_1 = require("./shared");
|
|
17
18
|
/**
|
|
18
19
|
* @param query
|
|
19
20
|
* @example loadHighestNPMVersionMatching("react@^18.3.0 || ^19.0.0") === Promise<"19.0.0">
|
|
@@ -31,6 +32,11 @@ async function loadHighestNPMVersionMatching(query) {
|
|
|
31
32
|
}
|
|
32
33
|
return versionOrVersions;
|
|
33
34
|
}
|
|
35
|
+
function endMessage() {
|
|
36
|
+
console.log();
|
|
37
|
+
console.log(picocolors_1.default.white(picocolors_1.default.bold(`Please review the local changes and read the Next.js 15 migration guide to complete the migration.`)));
|
|
38
|
+
console.log(picocolors_1.default.underline('https://nextjs.org/docs/canary/app/building-your-application/upgrading/version-15'));
|
|
39
|
+
}
|
|
34
40
|
async function runUpgrade(revision, options) {
|
|
35
41
|
const { verbose } = options;
|
|
36
42
|
const appPackageJsonPath = path_1.default.resolve(process.cwd(), 'package.json');
|
|
@@ -45,21 +51,25 @@ async function runUpgrade(revision, options) {
|
|
|
45
51
|
'version' in targetNextPackageJson &&
|
|
46
52
|
'peerDependencies' in targetNextPackageJson;
|
|
47
53
|
if (!validRevision) {
|
|
48
|
-
throw new
|
|
54
|
+
throw new shared_1.BadInput(`Invalid revision provided: "${revision}". Please provide a valid Next.js version or dist-tag (e.g. "latest", "canary", "rc", or "15.0.0").\nCheck available versions at https://www.npmjs.com/package/next?activeTab=versions.`);
|
|
49
55
|
}
|
|
50
56
|
const installedNextVersion = getInstalledNextVersion();
|
|
51
|
-
console.log(`Current Next.js version: v${installedNextVersion}`);
|
|
52
57
|
const targetNextVersion = targetNextPackageJson.version;
|
|
53
58
|
if ((0, compare_1.default)(installedNextVersion, targetNextVersion) === 0) {
|
|
54
59
|
console.log(`${picocolors_1.default.green('✓')} Current Next.js version is already on the target version "v${targetNextVersion}".`);
|
|
60
|
+
endMessage();
|
|
55
61
|
return;
|
|
56
62
|
}
|
|
57
63
|
if ((0, compare_1.default)(installedNextVersion, targetNextVersion) > 0) {
|
|
58
64
|
console.log(`${picocolors_1.default.green('✓')} Current Next.js version is higher than the target version "v${targetNextVersion}".`);
|
|
65
|
+
endMessage();
|
|
59
66
|
return;
|
|
60
67
|
}
|
|
61
68
|
const installedReactVersion = getInstalledReactVersion();
|
|
62
|
-
|
|
69
|
+
// Align the prefix spaces
|
|
70
|
+
console.log(` Detected installed versions:`);
|
|
71
|
+
console.log(` - React: v${installedReactVersion}`);
|
|
72
|
+
console.log(` - Next.js: v${installedNextVersion}`);
|
|
63
73
|
let shouldStayOnReact18 = false;
|
|
64
74
|
if (
|
|
65
75
|
// From release v14.3.0-canary.45, Next.js expects the React version to be 19.0.0-beta.0
|
|
@@ -111,29 +121,57 @@ async function runUpgrade(revision, options) {
|
|
|
111
121
|
execCommand = execCommandMap[packageManager];
|
|
112
122
|
}
|
|
113
123
|
fs_1.default.writeFileSync(appPackageJsonPath, JSON.stringify(appPackageJson, null, 2));
|
|
114
|
-
const
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
124
|
+
const dependenciesToInstall = [];
|
|
125
|
+
const devDependenciesToInstall = [];
|
|
126
|
+
const versionMapping = {
|
|
127
|
+
next: { version: targetNextVersion, required: true },
|
|
128
|
+
react: { version: targetReactVersion, required: true },
|
|
129
|
+
'react-dom': { version: targetReactVersion, required: true },
|
|
130
|
+
'react-is': { version: targetReactVersion, required: false },
|
|
131
|
+
};
|
|
119
132
|
if (targetReactVersion.startsWith('19.0.0-canary') ||
|
|
120
133
|
targetReactVersion.startsWith('19.0.0-beta') ||
|
|
121
134
|
targetReactVersion.startsWith('19.0.0-rc')) {
|
|
122
|
-
|
|
123
|
-
|
|
135
|
+
versionMapping['@types/react'] = {
|
|
136
|
+
version: `npm:types-react@rc`,
|
|
137
|
+
required: false,
|
|
138
|
+
};
|
|
139
|
+
versionMapping['@types/react-dom'] = {
|
|
140
|
+
version: `npm:types-react-dom@rc`,
|
|
141
|
+
required: false,
|
|
142
|
+
};
|
|
124
143
|
}
|
|
125
144
|
else {
|
|
126
145
|
const [targetReactTypesVersion, targetReactDOMTypesVersion] = await Promise.all([
|
|
127
146
|
loadHighestNPMVersionMatching(`@types/react@${targetNextPackageJson.peerDependencies['react']}`),
|
|
128
147
|
loadHighestNPMVersionMatching(`@types/react-dom@${targetNextPackageJson.peerDependencies['react']}`),
|
|
129
148
|
]);
|
|
130
|
-
|
|
131
|
-
|
|
149
|
+
versionMapping['@types/react'] = {
|
|
150
|
+
version: targetReactTypesVersion,
|
|
151
|
+
required: false,
|
|
152
|
+
};
|
|
153
|
+
versionMapping['@types/react-dom'] = {
|
|
154
|
+
version: targetReactDOMTypesVersion,
|
|
155
|
+
required: false,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
for (const [packageName, { version, required }] of Object.entries(versionMapping)) {
|
|
159
|
+
if (appPackageJson.devDependencies?.[packageName]) {
|
|
160
|
+
devDependenciesToInstall.push(`${packageName}@${version}`);
|
|
161
|
+
}
|
|
162
|
+
else if (required || appPackageJson.dependencies?.[packageName]) {
|
|
163
|
+
dependenciesToInstall.push(`${packageName}@${version}`);
|
|
164
|
+
}
|
|
132
165
|
}
|
|
133
166
|
console.log(`Upgrading your project to ${picocolors_1.default.blue('Next.js ' + targetNextVersion)}...\n`);
|
|
134
|
-
(0, handle_package_1.installPackages)(
|
|
167
|
+
(0, handle_package_1.installPackages)(dependenciesToInstall, {
|
|
168
|
+
packageManager,
|
|
169
|
+
silent: !verbose,
|
|
170
|
+
});
|
|
171
|
+
(0, handle_package_1.installPackages)(devDependenciesToInstall, {
|
|
135
172
|
packageManager,
|
|
136
173
|
silent: !verbose,
|
|
174
|
+
dev: true,
|
|
137
175
|
});
|
|
138
176
|
for (const codemod of codemods) {
|
|
139
177
|
await (0, transform_1.runTransform)(codemod, process.cwd(), { force: true, verbose });
|
|
@@ -159,7 +197,7 @@ async function runUpgrade(revision, options) {
|
|
|
159
197
|
if (codemods.length > 0) {
|
|
160
198
|
console.log(`${picocolors_1.default.green('✔')} Codemods have been applied successfully.`);
|
|
161
199
|
}
|
|
162
|
-
|
|
200
|
+
endMessage();
|
|
163
201
|
}
|
|
164
202
|
function getInstalledNextVersion() {
|
|
165
203
|
try {
|
|
@@ -168,7 +206,7 @@ function getInstalledNextVersion() {
|
|
|
168
206
|
})).version;
|
|
169
207
|
}
|
|
170
208
|
catch (error) {
|
|
171
|
-
throw new
|
|
209
|
+
throw new shared_1.BadInput(`Failed to get the installed Next.js version at "${process.cwd()}".\nIf you're using a monorepo, please run this command from the Next.js app directory.`, {
|
|
172
210
|
cause: error,
|
|
173
211
|
});
|
|
174
212
|
}
|
|
@@ -180,7 +218,7 @@ function getInstalledReactVersion() {
|
|
|
180
218
|
})).version;
|
|
181
219
|
}
|
|
182
220
|
catch (error) {
|
|
183
|
-
throw new
|
|
221
|
+
throw new shared_1.BadInput(`Failed to detect the installed React version in "${process.cwd()}".\nIf you're working in a monorepo, please run this command from the Next.js app directory.`, {
|
|
184
222
|
cause: error,
|
|
185
223
|
});
|
|
186
224
|
}
|
package/lib/handle-package.js
CHANGED
|
@@ -40,20 +40,44 @@ function uninstallPackage(packageToUninstall, pkgManager) {
|
|
|
40
40
|
command = 'remove';
|
|
41
41
|
}
|
|
42
42
|
try {
|
|
43
|
-
execa_1.default.sync(pkgManager, [command, packageToUninstall], {
|
|
43
|
+
execa_1.default.sync(pkgManager, [command, packageToUninstall], {
|
|
44
|
+
stdio: 'inherit',
|
|
45
|
+
shell: true,
|
|
46
|
+
});
|
|
44
47
|
}
|
|
45
48
|
catch (error) {
|
|
46
49
|
throw new Error(`Failed to uninstall "${packageToUninstall}". Please uninstall it manually.`, { cause: error });
|
|
47
50
|
}
|
|
48
51
|
}
|
|
52
|
+
const ADD_CMD_FLAG = {
|
|
53
|
+
npm: 'install',
|
|
54
|
+
yarn: 'add',
|
|
55
|
+
pnpm: 'add',
|
|
56
|
+
bun: 'add',
|
|
57
|
+
};
|
|
58
|
+
const DEV_DEP_FLAG = {
|
|
59
|
+
npm: '--save-dev',
|
|
60
|
+
yarn: '--dev',
|
|
61
|
+
pnpm: '--save-dev',
|
|
62
|
+
bun: '--dev',
|
|
63
|
+
};
|
|
49
64
|
function installPackages(packageToInstall, options = {}) {
|
|
50
|
-
|
|
65
|
+
if (packageToInstall.length === 0)
|
|
66
|
+
return;
|
|
67
|
+
const { packageManager = getPkgManager(process.cwd()), silent = false, dev = false, } = options;
|
|
51
68
|
if (!packageManager)
|
|
52
69
|
throw new Error('Failed to find package manager');
|
|
70
|
+
const addCmd = ADD_CMD_FLAG[packageManager];
|
|
71
|
+
const devDepFlag = dev ? DEV_DEP_FLAG[packageManager] : undefined;
|
|
72
|
+
const installFlags = [addCmd];
|
|
73
|
+
if (devDepFlag) {
|
|
74
|
+
installFlags.push(devDepFlag);
|
|
75
|
+
}
|
|
53
76
|
try {
|
|
54
|
-
execa_1.default.sync(packageManager, [
|
|
77
|
+
execa_1.default.sync(packageManager, [...installFlags, ...packageToInstall], {
|
|
55
78
|
// Keeping stderr since it'll likely be relevant later when it fails.
|
|
56
79
|
stdio: silent ? ['ignore', 'ignore', 'inherit'] : 'inherit',
|
|
80
|
+
shell: true,
|
|
57
81
|
});
|
|
58
82
|
}
|
|
59
83
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@next/codemod",
|
|
3
|
-
"version": "15.0.0-canary.
|
|
3
|
+
"version": "15.0.0-canary.192",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"@types/find-up": "4.0.0",
|
|
38
38
|
"@types/jscodeshift": "0.11.0",
|
|
39
39
|
"@types/prompts": "2.4.2",
|
|
40
|
-
"@types/semver": "7.3.1"
|
|
40
|
+
"@types/semver": "7.3.1",
|
|
41
|
+
"typescript": "5.5.3"
|
|
41
42
|
}
|
|
42
43
|
}
|