@next/codemod 16.1.0-canary.8 → 16.1.0
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 +1 -9
- package/bin/upgrade.js +50 -4
- package/package.json +1 -1
package/bin/next-codemod.js
CHANGED
|
@@ -39,15 +39,7 @@ const program = new commander_1.Command(packageJson.name)
|
|
|
39
39
|
program
|
|
40
40
|
.command('upgrade')
|
|
41
41
|
.description('Upgrade Next.js apps to desired versions with a single command.')
|
|
42
|
-
|
|
43
|
-
// versions of Next.js can still run the codemod successfully.
|
|
44
|
-
.argument('[revision]', 'Specify the target Next.js version using an NPM dist tag (e.g. "latest", "canary", "rc", "beta") or an exact version number (e.g. "15.0.0").', packageJson.version.includes('-canary.')
|
|
45
|
-
? 'canary'
|
|
46
|
-
: packageJson.version.includes('-rc.')
|
|
47
|
-
? 'rc'
|
|
48
|
-
: packageJson.version.includes('-beta.')
|
|
49
|
-
? 'beta'
|
|
50
|
-
: 'latest')
|
|
42
|
+
.argument('[revision]', 'Specify the upgrade type ("patch", "minor", "major"), an NPM dist tag (e.g. "latest", "canary", "rc"), or an exact version (e.g. "15.0.0"). Defaults to "minor".')
|
|
51
43
|
.usage('[revision] [options]')
|
|
52
44
|
.option('--verbose', 'Verbose output', false)
|
|
53
45
|
.action(async (revision, options) => {
|
package/bin/upgrade.js
CHANGED
|
@@ -90,24 +90,70 @@ function endMessage(targetNextVersion) {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
const cwd = process.cwd();
|
|
93
|
+
/**
|
|
94
|
+
* Resolves semantic version keywords (patch, minor, major) to npm version queries.
|
|
95
|
+
* - patch: latest patch within current minor (e.g., 15.0.x -> 15.0.y)
|
|
96
|
+
* - minor: latest minor within current major (e.g., 15.0.x -> 15.1.x)
|
|
97
|
+
* - major: latest stable version (equivalent to "latest")
|
|
98
|
+
*/
|
|
99
|
+
function resolveSemanticRevision(revision, installedVersion) {
|
|
100
|
+
const installedMajor = (0, semver_1.major)(installedVersion);
|
|
101
|
+
const installedMinor = (0, semver_1.minor)(installedVersion);
|
|
102
|
+
switch (revision) {
|
|
103
|
+
case 'patch':
|
|
104
|
+
// ~15.0.0 matches >=15.0.0 <15.1.0
|
|
105
|
+
return `~${installedMajor}.${installedMinor}.0`;
|
|
106
|
+
case 'minor':
|
|
107
|
+
// ^15.0.0 matches >=15.0.0 <16.0.0
|
|
108
|
+
return `^${installedMajor}.0.0`;
|
|
109
|
+
case 'major':
|
|
110
|
+
return 'latest';
|
|
111
|
+
default:
|
|
112
|
+
return revision;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
93
115
|
async function runUpgrade(revision, options) {
|
|
94
116
|
const { verbose } = options;
|
|
95
117
|
const appPackageJsonPath = path_1.default.resolve(cwd, 'package.json');
|
|
96
118
|
let appPackageJson = JSON.parse(fs_1.default.readFileSync(appPackageJsonPath, 'utf8'));
|
|
119
|
+
const installedNextVersion = getInstalledNextVersion();
|
|
120
|
+
// Resolve semantic keywords to npm version queries
|
|
121
|
+
const resolvedRevision = resolveSemanticRevision(revision ?? 'minor', installedNextVersion);
|
|
122
|
+
if (options.verbose) {
|
|
123
|
+
console.log(` Resolved upgrade target: ${resolvedRevision}`);
|
|
124
|
+
}
|
|
97
125
|
let targetNextPackageJson;
|
|
98
126
|
try {
|
|
99
|
-
|
|
127
|
+
// First, find the highest matching version
|
|
128
|
+
const versionsJSON = (0, child_process_1.execSync)(`npm --silent view "next@${resolvedRevision}" --json --field version`, { encoding: 'utf-8' });
|
|
129
|
+
const versionOrVersions = JSON.parse(versionsJSON);
|
|
130
|
+
let targetVersion;
|
|
131
|
+
if (Array.isArray(versionOrVersions)) {
|
|
132
|
+
versionOrVersions.sort(semver_1.compare);
|
|
133
|
+
targetVersion = versionOrVersions[versionOrVersions.length - 1];
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
targetVersion = versionOrVersions;
|
|
137
|
+
}
|
|
138
|
+
if (options.verbose) {
|
|
139
|
+
console.log(` Target version: ${targetVersion}`);
|
|
140
|
+
}
|
|
141
|
+
// Then fetch the full package info for that specific version
|
|
142
|
+
const targetNextPackage = (0, child_process_1.execSync)(`npm --silent view "next@${targetVersion}" --json`, { encoding: 'utf-8' });
|
|
100
143
|
targetNextPackageJson = JSON.parse(targetNextPackage);
|
|
101
144
|
}
|
|
102
|
-
catch {
|
|
145
|
+
catch (e) {
|
|
146
|
+
if (options.verbose) {
|
|
147
|
+
console.error(' Error fetching package info:', e);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
103
150
|
const validRevision = targetNextPackageJson !== null &&
|
|
104
151
|
typeof targetNextPackageJson === 'object' &&
|
|
105
152
|
'version' in targetNextPackageJson &&
|
|
106
153
|
'peerDependencies' in targetNextPackageJson;
|
|
107
154
|
if (!validRevision) {
|
|
108
|
-
throw new shared_1.BadInput(`Invalid revision provided: "${revision}". Please provide a valid Next.js version
|
|
155
|
+
throw new shared_1.BadInput(`Invalid revision provided: "${revision ?? 'minor'}" (resolved to "${resolvedRevision}"). Please provide a valid Next.js version, dist-tag (e.g. "latest", "canary", "rc"), or upgrade type ("patch", "minor", "major").\nCheck available versions at https://www.npmjs.com/package/next?activeTab=versions.`);
|
|
109
156
|
}
|
|
110
|
-
const installedNextVersion = getInstalledNextVersion();
|
|
111
157
|
const targetNextVersion = targetNextPackageJson.version;
|
|
112
158
|
if ((0, semver_1.compare)(installedNextVersion, targetNextVersion) === 0) {
|
|
113
159
|
console.log(`${picocolors_1.default.green('✓')} Current Next.js version is already on the target version "v${targetNextVersion}".`);
|